Question:
I’m building a game in C++ where I need to create and manage a grid of cells using pointers. The grid is represented by a linked structure, where each cell has pointers to its neighbors (including up, down, left, right, etc.). However, when trying to print the grid, only the top row is displayed, and the row->neighbours[4] (which is supposed to move to the next row) becomes nullptr after the first iteration.
I believe I’ve linked the pointers correctly, but I’m not sure why this happens. Here is my code, and I’m hoping someone can help identify what might be wrong.
// file coffee_board.cc
#include <iostream>
#include "coffee_board.h"
using namespace std;
//--------------------------------------------------------------------
// Inputs from user when typing in the desired option
// Reads a character input while ignoring newlines
char get_input() {
char input; // Input from user
input = cin.get(); // Read input from user
while (input == '\n') { // Keeps going until first not enter
input = cin.get(); // Reads first input not enter
}
return input; // returns first not enter input
}
// Reads a number input while ignoring newlines
int get_number() {
char input;
input = get_input(); // Get input from user (not new line)
int number = 0; // Number from user input initially at 0
int out_number = 0; // Number output
while (input != '\n') { // Keep reading until enter
if ('0' <= input && input <= '9') { // Numerical characters
number = 10 * number + input - '0'; // Append new digits
}
if (number <= 1000) { // Sets number max to 1000
out_number = number; // If Number > 1000 no output change
}
input = cin.get(); // Get input from user
}
return out_number; // Return number <= 1000
}
//--------------------------------------------------------------------
void coffee_board::get_height() {
cout << "Enter the height of the board (minimum 1): ";
height = get_number();
while (height < 1) { // Ensure height is valid
cout << "Invalid input. Height must be at least 1. Enter again: ";
height = get_number();
}
}
void coffee_board::get_width() {
cout << "Enter the width of the board (minimum 1): ";
width = get_number();
while (width < 1) { // Ensure width is valid
cout << "Invalid input. Width must be at least 1. Enter again: ";
width = get_number();
}
}
void coffee_board::get_percentage() {
cout << "Enter the percentage of coffee cups (min:0 ; max:100): ";
percentage = get_number();
while (percentage < 0 || percentage > 100) {
cout << "Invalid input. Percentage must be between 0 and 100. Enter again: ";
percentage = get_number();
}
}
void coffee_board::dimensions() {
get_height(); // Call to get height
get_width(); // Call to get width
get_percentage(); // Call to get percentage of coffee
}
//--------------------------------------------------------------------
grid::grid ( ) {
for(int i=0; i<8; i++){
neighbours[i]=nullptr;
}
}
coffee_board::coffee_board ( ) {
input = nullptr;
}
coffee_board::~coffee_board ( ) {
// TODO
}
void coffee_board::make_row(grid*& input) {
grid* head = nullptr;
grid* tail = nullptr;
for (int i = 1; i <= width; i++) {
grid* temp = new grid();
temp->neighbours[6] = tail;
if (tail != nullptr) {
tail->neighbours[2] = temp;
} else {
head = temp;
}
tail = temp;
}
input = head;
}
void coffee_board::link(grid* upper_row, grid* lower_row) {
grid* temp_above = upper_row;
grid* temp_below = lower_row;
while (temp_below != nullptr && temp_above != nullptr) {
temp_above->neighbours[3] = temp_below->neighbours[2];
temp_above->neighbours[4] = temp_below;
temp_above->neighbours[5] = temp_below->neighbours[6];
temp_below->neighbours[7] = temp_above->neighbours[6];
temp_below->neighbours[0] = temp_above;
temp_below->neighbours[1] = temp_above->neighbours[2];
temp_below = temp_below->neighbours[2];
temp_above = temp_above->neighbours[2];
}
}
void coffee_board::build() {
grid* prev_row = nullptr;
grid* next_row = nullptr;
make_row(next_row); // Create the first row
prev_row = next_row; // Set the first row as previous
for (int i = 1; i < height; i++) {
make_row(next_row); // Create the next row
link(prev_row, next_row); // Link the previous row to the current row
prev_row = next_row; // Move to the next row
}
input = prev_row; // Set the last row as the board's starting point
}
void coffee_board::print() {
if (input == nullptr) {
cout << "Empty board\n";
return;
}
grid* row = input;
grid* temp = nullptr;
// Print column numbers
cout << " ";
for (int col_num = 1; col_num <= width; col_num++) {
if (col_num <= 9) {
cout << "0" << col_num << " ";
} else {
cout << col_num << " ";
}
}
cout << endl;
// Print the grid
for (int row_num = 1; row_num <= height; row_num++) {
// Print row numbers
if (row_num <= 9) {
cout << "0" << row_num << " ";
} else {
cout << row_num << " ";
}
temp = row;
while (temp != nullptr) {
cout << " .";
temp = temp->neighbours[2]; // Move to the next column in the same row
}
cout << endl;
// Move to the next row
if (row != nullptr) {
row = row->neighbours[4]; // Move to the next row (downwards)
}
}
}
This is the second file
// file coffee_board.h
class grid {
public:
bool open;
int number; // 7 0 1
grid* neighbours[8]; // 6 2
grid ( ); // 5 4 3
// TODO
};
class coffee_board {
private:
grid* input;
int height=15; // Board height
int width=15; // Board width
int percentage;
int coffee_count; // New variable to track total coffees
public:
coffee_board(); //
~coffee_board(); // deconstructor
void dimensions();
void get_height(); // Function to get height
void get_width(); // Function to get width
void get_percentage(); // Function to get percentage of coffee
void make_row(grid*& input);
void link(grid* upper_row, grid* lower_row);
void build();
void print();
// TODO
};
This is the main file:
// file main.cc
#include <iostream>
#include "coffee_board.h"
using namespace std;
int main ( ) {
coffee_board Coffee_board;
Coffee_board.dimensions();
Coffee_board.build();
Coffee_board.print();
return 0;
}//main
And this is the makefile:
# makefile
all: main.o coffee_board.o
g++ -Wall -Wextra -o hetspel coffee_board.o main.o
coffee_board.o: coffee_board.cc coffee_board.h
g++ -Wall -Wextra -c coffee_board.cc
main.o: main.cc coffee_board.h
g++ -Wall -Wextra -c main.cc
Problem:
The issue is that when trying to print the grid, only the top row is displayed. The statement row = row->neighbours[4] is supposed to move down to the next row, but after the first iteration, row->neighbours[4] becomes nullptr, causing the bottom dots not to be printed.
What I’ve Tried:
I have checked the link() function, which seems to properly set up the neighboring pointers between rows. However, the issue seems to occur when trying to traverse the rows in the print() function. The top row prints fine, but subsequent rows don’t display, as row->neighbours[4] becomes nullptr after the first row.
Questions:
Is there something wrong with how I’m linking the rows in the link() function, especially when using neighbours[4]?
Could there be an issue with how I’m initializing the grid cells in make_row()?
How can I debug the issue to ensure the row pointers are correctly assigned?
Here’s a picture of what happens:
>Solution :
I think the problem can be illustrated with this line of code
input = prev_row; // Set the last row as the board's starting point
The last/bottom row is the starting point, yet clearly when you print you are expecting the first/top row to be the starting point.
Either fix coffee_board::build() or try row = row->neighbours[0] in coffee_board::print().
