How can I print a board using a two dimensional array? - c++

I want to print a 5x5 board for a game, at the moment I can only print 5 lines while populating the array. My board currently looks like this:
Which is technically a 2 row 5 columns board.
This is the output I expect:
The problem is that I need a 5x5 version of that same board but it only prints 5 lines (which is the size of the array).
I've tried changing the for loop many times but nothing has worked so far
This is my code:
//
// Created by renan on 31/08/2019.
//
#include <iomanip>
#include <iostream>
#include "Board.h"
void Board::displayBoard() {
for (int row = 0; row < ROWS; row++) { //ROWS and COLS
are integers with value 5
for (int col = 0; col < COLS; col++) {
board[row][col] = ' ';
if (row % 2 == 0) {
cout << " ---";
} else {
if (col == 0) {
cout << "|";
}
if(board[row][col] == ' '){
cout << setw(4) << "|";
} else {
cout << setw(1) << board[row][col] << " |";
}
}
}
cout << endl;
}
}
Board.h
#include <iostream>
using namespace std;
class Board {
private:
static const int ROWS = 11;
static const int COLS = 5;
char board[ROWS][COLS];
public:
void displayBoard();
};

I corrected and simplified your code a bit. Hope it will help you to understand what was wrong with your code.
void drawHorizontalSeparater() {
for (int i = 0; i < 5; i++) {
cout << " ---";
}
cout << endl;
}
void drawSeparatedValues(int row) {
cout << "|";
for (int col = 0; col < 5; col++) {
board[row][col] = ' ';
cout << " " << board[row][col] << " |";
}
cout << endl;
}
void displayBoard() {
drawHorizontalSeparater();
for (int row = 0; row < 5; row++) {
drawSeparatedValues(row);
drawHorizontalSeparater();
}
}
Result:
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---

Related

How can I print the empty spaces with " | | " until the line ends [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
I am working with vectors and I wanna know how I can print the empty spaces in between until the line ends.
void print_vector(const std::vector < int > & v, int print_cols, int col_width) {
//dash
cout << string(print_cols * (col_width + 2) + 1, '-');
cout << endl;
//printing the vector in formated output
cout << "|";
for (size_t x = 0; x < v.size(); x++) {
cout << right << setw(col_width) << v[x] << " |";
//prints new line if it reaches limit of numbers per line
if ((x + 1) % print_cols == 0) cout << endl << "|";
}
//dash
cout << endl << string(print_cols * (col_width + 2) + 1, '-');
cout << endl;
}
this is my current output: my output so far and sorry I can't embed images yet it wont let me.
But this is the output that I want output needed
void print_vector(const std::vector < int > & v, int print_cols, int col_width) {
//dash
cout << string(print_cols * (col_width + 2) + 1, '-');
cout << endl;
//printing the vector in formated output
cout << "|";
size_t x = 0;
for (x = 0; x < v.size(); x++) {
cout << right << setw(col_width) << v[x] << " |";
//prints new line if it reaches limit of numbers per line
if (x < v.size() - 1) {
if ((x + 1) % print_cols == 0) {
cout << endl << "|";
}
}
}
size_t remain = print_cols - (x % print_cols);
for (size_t i = 0; (remain != print_cols) && i < remain; ++i) {
cout << right << setw(col_width) << " " << " |";
}
//dash
cout << endl << string(print_cols * (col_width + 2) + 1, '-');
cout << endl;
}
Sample outputs:
-------------------------------------------------
| 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 |
| 9 | | | |
-------------------------------------------------
-------------------------------------
| 1 | 2 | 3 |
| 4 | 5 | 6 |
| 7 | 8 | 9 |
-------------------------------------
You can add an extra loop after the one you have and before the bottom row of dashes:
The loop would print a given number of blank columns.
The number of blank columns can be computed as print_cols - v.size() % print_cols.
The loop should not be executed if the number of blank columns is equal to the total number of columns. That would print a full row of empty columns. That case happens when the vector you want to print has a number of elements that is an exact multiple of the number of columns.
Every iteration of the loop should print col_width + 1 blanks and a '|' (or if you prefer it, to make it more consistent with your other code, col_width blanks plus a " |").
Yet you should fix another issue with your code:
The check for reaching the end of the row (enabling the print of a new line and a '|') should be instead a check for starting a row.
 
If you do it at the end, for the case when the last element of the vector goes in the last column, you will unnecessarily add a new row.
 
Doing it at the beginning, since you know you have at least one more number to show, you can print "\n|" and then the number.
 
The check x % print_cols == 0 will tell you if x is the index of the first element of a row.
[Demo]
#include <iomanip> // setw
#include <iostream> // cout
#include <numeric> // iota
#include <string>
#include <vector>
void print_vector(const std::vector<int>& v, int print_cols, int col_width) {
// dash
std::cout << std::string(print_cols * (col_width + 2) + 1, '-');
// printing the vector in formated output
for (size_t x = 0; x < v.size(); x++) {
// prints new line if it is the first element of the line
if (x % print_cols == 0) {
std::cout << "\n|";
}
std::cout << std::right << std::setw(col_width) << v[x] << " |";
}
// prints last empty columns
if (int number_of_blank_columns = print_cols - v.size() % print_cols;
number_of_blank_columns != print_cols) {
for (int x = 0; x < number_of_blank_columns; x++) {
std::cout << std::string(col_width + 1, ' ') << "|";
}
}
// dash
std::cout << "\n" << std::string(print_cols * (col_width + 2) + 1, '-') << "\n";
}
int main() {
{
std::vector<int> v(8);
std::iota(std::begin(v), std::end(v), 100);
print_vector(v, 5, 4);
}
std::cout << "\n";
{
std::vector<int> v(10);
std::iota(std::begin(v), std::end(v), 100);
print_vector(v, 5, 4);
}
}
// Outputs:
//
// -------------------------------
// | 100 | 101 | 102 | 103 | 104 |
// | 105 | 106 | 107 | | |
// -------------------------------
//
// -------------------------------
// | 100 | 101 | 102 | 103 | 104 |
// | 105 | 106 | 107 | 108 | 109 |
// -------------------------------

Print out a text in the middle of a rectangle

I want to print out a rectangle and in the middle I want to output a preferred text.
So In the terminal it should look like:
Enter width and height: 5 6
+-----+
| |
| |
| |
| |
| |
+-----+
Then in the middle of the rectangle (height/2) it should print out "Hey". It doesn't fit in this example because the format on reddit is a bit different than my compiler.
However I wonder how I could make this happen? I can create the rectangle but I cannot seem to create a "when" statement, as in "when mid occurs, print out "Hey".
I need help finding a way to write such statement.
Here is my code:
#include <iostream>
#include <iomanip>
using namespace std;
void print_row (int const width)
{
cout << '+' << '-';
for (int i = 1; i < width; ++i)
{
cout << '-';
}
cout << '+' << endl;
}
void print_rectangle (int const width, int const height)
{
int mid = height/2;
print_row(width);
for (int i {}; i < height; ++i)
{
cout << '|' << setw(width+1) << '|' << endl;
if (mid)
{
cout << "Hey" << endl;
}
}
print_row(width);
}
int main()
{
int width {};
int height {};
cout << "Enter width and height: ";
cin >> width >> height;
print_rectangle(width,height);
return 0;
}
first of all validate your width and height in your print_rectangle
String output = "hey";
if(width < output.length() || height <= 0) return;
and change the for loop like this
for (int i = 0; i < height; ++i) {
if (i == mid) {
int spacing = width - output.length();
cout <<'|'<< setw(width-spacing/2) << output << setw(spacing/2+1) << '|' << endl;
continue;
}
cout << '|' << setw(width+1) << '|' << endl;
}

Rectangular shape with characters inside it placed with a certain width

I am trying to replicate this:
Type the height and width of the rectangle: 10 13
+-------------+
| w w w |
| w w w |
| w w w |
|w w w w|
| w w w |
| w w w |
| w w w |
|w w w w|
| w w w |
| w w w |
+-------------+
Type the height and width of the rectangle: 0 0
+-+
+-+
Type the height and width of the rectangle: 4 1
+-+
| |
| |
| |
|w|
+-+
I succesfully made a subprogram that printed out the rectangle (though it is messy and there's obvious duplications of code). How can I, in the same subprogram (or maybe in a different one) print out the 'w' and the empty spaces filled with spaces? The width of each 'w' is 4 spaces. I kind of have an idea. That we do cout << setfill(' ') << setw(4) << 'w' and then an if-statement that if the setw exceeds <= width it will do a '\n'
However this is my code and I would much appreciate how my code could be improven and how to implement a character with width 4 inside the rectangle.
#include <iostream>
#include <iomanip>
using namespace std;
void print_rectangle (int const width,
int const height)
{
cout << '+' << '-';
for (int i {1}; i < width; ++i)
{
cout << '-';
}
cout << '+' << endl;
for (int j {}; j < height; ++j)
{
cout << '|' << setw(width + 1) << '|' << endl;
}
cout << '+' << '-';
for (int i {1}; i < width; ++i)
{
cout << '-';
}
cout << '+' << endl;
}
int main()
{
int width {};
int height {};
cout << "Enter the height and width of the rectangle: ";
cin >> height;
cin >> width;
print_rectangle(width,height);
return 0;
}
Well the solution for the second part which will print the 'w' and the spaces is as follows:
#include <iostream>
#include <iomanip>
using namespace std;
void print_rectangle (int const width,
int const height)
{
int counter=1;
int remainder= (width+1) % height;
cout << '+' << '-';
for (int i = 1; i < width; ++i)
{
cout << '-';
}
cout << '+' << endl;
for (int j =0 ; j < height; ++j)
{
if(j == 0 || j == height )
cout << '|' << setw(width + 1) << '|' << endl;
else
{
cout << '|';
for (int i = 0; i <width ; i++)
{
if(counter % remainder == 0)
cout<<"w";
else
cout<<" ";
counter++;
}
cout << '|'<<endl;
}
}
cout << '+' << '-';
for (int i =1 ; i < width; ++i)
{
cout << '-';
}
cout << '+' << endl;
}
int main()
{
int width =0;
int height =0;
cout << "Enter the height and width of the rectangle: ";
cin >> height;
cin >> width;
print_rectangle(width,height);
return 0;
}
I have tested the given input cases on it as well and it gives the right output. What's happening here is that the remainder of height and width+1 gives us a remainder and with the help of that remainder we are going to print w's. A counter is incremented in the loop and whenever that counter is a multiple of that remainder w will be printed otherwise space.
Here is the output of the test case input 4 and 1 output
And here is the output of test case input 10 and 13
Please learn split problem to smaller pieces which are a small functions.
Take a look on this:
using std::setw;
void print_ending(std::ostream& out, int const width) {
out << '+' << std::string(width, '-') << '+' << '\n';
}
void print_row(std::ostream& out,
int const width,
int const period,
int offset) {
out << '|' << std::string(std::min(width, offset), ' ');
if (offset < width) {
out << 'w';
auto remainin_width = width - offset - 1;
for (int i = remainin_width / period; i > 0; --i) {
out << setw(period) << 'w';
}
out << std::string(remainin_width % period, ' ');
}
out << "|\n";
}
void print_rectangle(std::ostream& out,
int const width,
int const height,
int period = 4) {
print_ending(out, width);
for (int j{}; j < height; ++j) {
print_row(out, width, period, (height - j) % period);
}
print_ending(out, width);
}
Live demo

How to make an output file of n*n matrix,by taking n from the user, with the numbers generated in pairs?

Currently I have a pre-made 6X6 matrix in a text file like this:
2 6 3 1 0 4
4 2 7 7 2 8
4 7 3 2 5 1
7 6 5 1 1 0
8 4 6 0 0 6
1 3 1 8 3 8
and I made a code that is reading from a file i have made. However I want to have user make a grid for themselves (i.e. 3X3 or 10X10). Which then writes to a text file automatically like in similar fashion and then have that read-in instead. It is a basic memory match card game, so I need to have rand() which generates equal pair so the game can be over when every pair in the grid has been found. Thank you so much for your time!
/*Here are the snippets of my code*/
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <fstream>
#include <string>
#include <numeric>
#include <limits>
using namespace std;
//global 2d vectors that are associated with the game
vector<vector<int> > game_grid;
vector<vector<int> > hidden_grid;
vector <vector<int> > guessed;
void initialize_grid() {
ifstream input_file;
input_file.open("grid.txt");
int num;
if (input_file) {
for (int i = 0; i < 6; ++i) {
vector<int> row; // game grid
vector<int> row2; // hidden grid
vector<int> row3; // guessed grid
for (int j = 0; j < 6; ++j) {
if (input_file >> num)
row.push_back(num);
row2.push_back(-1);
row3.push_back(0);
}
game_grid.push_back(row);
hidden_grid.push_back(row2);
guessed.push_back(row3);
}
cout << "Get is ready, Challenger!" << endl << endl;
}
else {
cout << "Womp. File open failed!";
}
return;
}
void print_grid() {
cout << "Game grid" << endl;
cout << " -------------------------" << endl;
for (int i = 0; i < 6; ++i) {
cout << " | ";
for (int j = 0; j < 6; ++j) {
cout << game_grid[i][j] << " | ";
}
cout << endl << " -------------------------" << endl;
}
cout << endl;
}
void print_hidden_grid(int r1 = -1, int r2 = -1, int c1 = -1, int c2 = -1) {
cout << "Attempt:" << endl;
if (r1 != -1) {
hidden_grid[r1][c1] = game_grid[r1][c1];
}
if (r2 != -1) {
hidden_grid[r2][c2] = game_grid[r2][c2];
}
for (int i = 0; i < 6; ++i) {
cout << " | ";
for (int j = 0; j < 6; ++j) {
if (hidden_grid[i][j] > -1)
cout << hidden_grid[i][j] << " | ";
else
cout << " | ";
}
cout << endl << " -------------------------" << endl;
}
cout << endl;
if (r1 != -1) {
if (game_grid[r1][c1] == game_grid[r2][c2]) {
guessed[r1][c1] = 1;
guessed[r2][c2] = 1;
cout << "You have a match!" << endl << endl;
}
else {
hidden_grid[r1][c1] = -1;
hidden_grid[r2][c2] = -1;
}
}
cout << endl << endl;
}
void print_current_grid() {
cout << "Current Grid:" << endl;
cout << " -------------------------" << endl;
for (int i = 0; i < 6; ++i) {
cout << " | ";
for (int j = 0; j < 6; ++j) {
if (hidden_grid[i][j] > -1)
cout << hidden_grid[i][j] << " | ";
else
cout << " | ";
}
cout << endl << " -------------------------" << endl;
}
cout << endl << endl;
}
.......
If I well understand you want to auto detect the size of the matrix when you read it ? If yes you can do something like that in initialize_grid :
void initialize_grid() {
ifstream input_file;
input_file.open("grid.txt");
int num;
if (input_file) {
// detect size
int size = 0;
string line;
if (!getline(input_file, line))
return;
istringstream iss(line);
while (iss >> num)
size += 1;
input_file.clear();
input_file.seekg(0);
for (int i = 0; i < size; ++i) {
vector<int> row; // game grid
vector<int> row2; // hidden grid
vector<int> row3; // guessed grid
for (int j = 0; j < size; ++j) {
if (input_file >> num)
row.push_back(num);
row2.push_back(-1);
row3.push_back(0);
}
game_grid.push_back(row);
hidden_grid.push_back(row2);
guessed.push_back(row3);
}
cout << "Get is ready, Challenger!" << endl << endl;
}
else {
cout << "Womp. File open failed!";
}
}
and else where you replace 6 by game_grid.size() (using size_t rather than int to type the indexes)

Printing a grid

I want to print a game board grid which will vary in size depending on what the user inputs. I also wanted to know would it be best or even be possible to make this same grid using an array or would I need some type of 2d array of some sort?
void printGrid(int &userRows, int &userColumns){
cout << "Enter the number of rows -> ";
cin >> userRows;
cout << "Enter the number of columns -> ";
cin >> userColumns;
for(int i = 0; i < userColumns; i++){
cout << "|";
for(int y = 0; y < userRows; y++){
cout << "-";
}
}
}
I got the nested loop part down pat. Just having an issue telling it to print a new line and to spawn one after the other. Thank you
Here is the final product I am going for
I got the nested loop part down pat. Just having an issue telling it to print a new line and to spawn one after the other.
Are you sure? That doesn't seem to produce anything close to the final product I am going for?
While that may produce "|" and "-" output, it ignores the column headings, the header separator, the row labels, the footer separator and the column footer.
In answer to the newline part of your question, you have two options, you can either output a newline with the macro endl or you can output a literal newline "\n". If you have declared using namespace std;, you can simply use the cout << endl; or cout << "\n";. otherwise you need to explicitly specify the std namespace, e.g. std::cout << endl; or std::cout << "\n";
To finish building your output with column heading, separators, row labels, footer separator and footer, just take it piece-by-piece. For example for your column headings, you could simply loop over your columns, outputting your loop counter + 1 with appropriate spacings:
for (int i = 0; i < cols; i++) /* output column headings */
if (!i)
std::cout <<" " << i+1;
else
std::cout <<" " << i+1;
std::cout << "\n";
(note: the use of the if (!i) (equivalent to if (i == 0)) to handle the first-column spacing separately)
For your heading separator, you could loop over the columns again, in like manner with the same check handling the first column differently.
for (int i = 0; i < cols; i++) /* output header separators */
if (!i)
std::cout <<" ---";
else
std::cout <<" ---";
std::cout << "\n";
Then the actual grid sections requires row-labels both before, and after, each row of the grid is output. Here you simply add a nested loop to loop over each row, but otherwise use a similar loop over each column with first row check, followed by a final output of the closing row-label for each row:
for (int i = 0; i < rows; i++) { /* output labeled grid rows */
for (int j = 0; j < cols; j++)
if (!j)
std::cout << (char)('A' + i) << " | |";
else
std::cout << " |";
std::cout << " " << (char)('A' + i) << "\n";
}
Finally, you just repeat what you did for the column headers and header separator in reverse order for your footer separator and footer, outputting the separator row first followed by the column footers, e.g.
for (int i = 0; i < cols; i++) /* output footer separators */
if (!i)
std::cout <<" ---";
else
std::cout <<" ---";
std::cout << "\n";
for (int i = 0; i < cols; i++) /* output column footer */
if (!i)
std::cout <<" " << i+1;
else
std::cout <<" " << i+1;
std::cout << "\n"; /* tidy up with new line */
That's pretty much it. You can throw together a short example using a class board to hold the rows and cols values and a constructor and a couple of member functions to update or request input for new row/column values, e.g. the following just outputs your 4x6 grid, then prompts for new rows and cols values, and finally output a 5x7 example:
#include <iostream>
class board {
int rows, cols;
public:
board() {};
board (int x, int y) { rows = x; cols = y; }
void prngrid ();
void setsize (int x, int y) { rows = x; cols = y; }
void setsize ();
};
void board::prngrid ()
{
std::cout << "\n"; /* output new line before grid */
for (int i = 0; i < cols; i++) /* output column headings */
if (!i)
std::cout <<" " << i+1;
else
std::cout <<" " << i+1;
std::cout << "\n";
for (int i = 0; i < cols; i++) /* output header separators */
if (!i)
std::cout <<" ---";
else
std::cout <<" ---";
std::cout << "\n";
for (int i = 0; i < rows; i++) { /* output labeled grid rows */
for (int j = 0; j < cols; j++)
if (!j)
std::cout << (char)('A' + i) << " | |";
else
std::cout << " |";
std::cout << " " << (char)('A' + i) << "\n";
}
for (int i = 0; i < cols; i++) /* output footer separators */
if (!i)
std::cout <<" ---";
else
std::cout <<" ---";
std::cout << "\n";
for (int i = 0; i < cols; i++) /* output column footer */
if (!i)
std::cout <<" " << i+1;
else
std::cout <<" " << i+1;
std::cout << "\n"; /* tidy up with new line */
}
void board::setsize ()
{
std::cout << "\nenter the number of rows -> ";
std::cin >> rows;
std::cout << "enter the number of cols -> ";
std::cin >> cols;
}
int main (void) {
board board1 (4, 6);
board1.prngrid();
board1.setsize();
board1.prngrid();
board1.setsize (5,7);
board1.prngrid();
return 0;
}
(note: you should add validation checks that rows and cols values are non-negative (or choose an unsigned type), and also check that they are reasonable for your screen output (e.g. less than 20 or so and at least 26 or less or you will run out of upper-case letters). Those checks, and adjustments for multi-digit headings, are left to you)
Example Use/Output
$ ./bin/board_grid
1 2 3 4 5 6
--- --- --- --- --- ---
A | | | | | | | A
B | | | | | | | B
C | | | | | | | C
D | | | | | | | D
--- --- --- --- --- ---
1 2 3 4 5 6
enter the number of rows -> 5
enter the number of cols -> 5
1 2 3 4 5
--- --- --- --- ---
A | | | | | | A
B | | | | | | B
C | | | | | | C
D | | | | | | D
E | | | | | | E
--- --- --- --- ---
1 2 3 4 5
1 2 3 4 5 6 7
--- --- --- --- --- --- ---
A | | | | | | | | A
B | | | | | | | | B
C | | | | | | | | C
D | | | | | | | | D
E | | | | | | | | E
--- --- --- --- --- --- ---
1 2 3 4 5 6 7
Look things over and let me know if you have further questions.
The problem is fairly easy, just understand the pattern! Here's the working code with live example.
#include <iostream>
using namespace std;
void printGrid(int &userRows, int &userColumns){
cout<<endl;
cout<<" ";
int i=1,j;
for(j = 0; j <= 4*userColumns; j++){
if(j%4==2)
cout<<i++;
else cout<<" ";
}
cout<<endl;
for(i = 0; i <= 2*userRows; i++){
if(i%2!=0)
cout<<(char)(i/2 +'A');
for(j = 0; j <= 2*userColumns; j++){
if(i%2==0)
{
if(j==0)
cout<<" ";
if(j%2==0)
cout<<" ";
else cout<<"---";
}
else{
if(j%2==0)
cout<<"|";
else cout<<" ";
}
}
if(i%2!=0)
cout<<(char)(i/2 +'A');
cout<<endl;
}
cout<<" ";
for(j = 0, i = 1; j <= 4*userColumns; j++){
if(j%4==2)
cout<<i++;
else cout<<" ";
}
cout<<endl;
}
int main() {
int userRows, userColumns;
cout << "Enter the number of rows -> ";
cin >> userRows;
cout << "Enter the number of columns -> ";
cin >> userColumns;
printGrid(userRows, userColumns);
return 0;
}
Live Code
Output:
Enter the number of rows -> 4
Enter the number of columns -> 6
1 2 3 4 5 6
--- --- --- --- --- ---
A| | | | | | |A
--- --- --- --- --- ---
B| | | | | | |B
--- --- --- --- --- ---
C| | | | | | |C
--- --- --- --- --- ---
D| | | | | | |D
--- --- --- --- --- ---
1 2 3 4 5 6
By adding the cout << endl; after the userRows for-loop has finish the process it will proceed with the next line until i < userColumns
for(int i = 0; i < userColumns; i++){
cout << "|";
for(int y = 0; y < userRows; y++){
cout << "-";
}
cout << endl; //end of every-line
}
When you say:
make this same grid using an array
I'm guessing you are asking how to handle values you can use to populate the grid. There are lots of ways to store a variable number of values. Here are a few (I'm assuming the values are of type char):
One dimensional std::vector
std::vector<char> gridValues;
gridValues.resize(userColumns * userRows);
Then, inside the for loops:
cout << gridValues.at( i + y*userColumns );
Two dimensional std::vector
std::vector<std::vector<char>> gridValues;
gridValues.resize(userRows);
for( int i = 0; i < userRows; ++i )
gridValues.at(i).resize(userColumns);
Then, inside the for loops:
cout << gridValues.at( y ).at( i );
One dimensional array
char* gridValues = new char[ userColumns*userRows ];
Then, inside the for loops:
cout << gridValues[ i + y*userColumns ];
Two dimensional array
char** gridValues = new char[ userRows ];
for( int i = 0; i < userRows; ++i )
gridValues[i] = new char[ userColumns ];
Then, inside the for loops:
cout << gridValues[ y ][ i ];
I would use the one-dimensional std::vector, because it's simple to setup and I don't have to worry about forgetting to delete the pointers at the end.
As a note, you may want to check you for loops. With userColumns = 3 and userRows = 2, the code you gave will print: |--|--|--. The variables are being used backwards.
Once you fix the order of the loops, JaxLee's answer will help you put the newline in the right spot.