Question

This my first post on stackoverflow so hopefully what I have posted adheres to correct guidelines/format on this forum site.

I am new to C++ so please bear with me. I am trying to implement a sudoku solver in C++ and 1 of my objectives is to read in a sudoku puzzle which is 9x9 grid, into an object array, specifically a 2D array and then display it's contents onto the command window.

The sudoku puzzle given is in the following format:

0 3 0 0 0 1 0 7 0
6 0 0 8 0 0 0 0 2
0 0 1 0 4 0 5 0 0
0 7 0 0 0 2 0 4 0
2 0 0 0 9 0 0 0 6
0 4 0 3 0 0 0 1 0
0 0 5 0 3 0 4 0 0
1 0 0 0 0 6 0 0 5
0 2 0 1 0 0 0 3 0

What I have in my header file (sudoku_header.h) is the following:

#pragma once
#ifndef SUDOKU_HEADER
#define SUDOKU_HEADER
#include <vector>

using namespace std;

class Cell
{
public:
    friend istream& operator >>(istream &input, Cell& cellObject);
    friend ostream& operator <<(ostream &output, Cell& cellObject);
    bool ValueGiven();
    void AssignCell(int num);               // assigns a number to a cell on the puzzle board
    void PopulateRows();
private:
    int row, column, block;                     // triple context i.e. row, column and block
    vector<int> candidateList;                  // holds a vector of all the possible candidates for a given cell
};

istream& operator >>(istream& input, Cell& cellObject)
{
    input >> cellObject.row;
    input >> cellObject.column;

    return input;
}

ostream& operator <<(ostream& output, Cell& cellObject)
{
    output << cellObject;

    return output;
}

#endif 

and this is whats inside my main.cpp file:

#include <iostream>
#include <fstream>
#include <ostream>
#include <istream>
#include "sudoku_header.h"

void PopulateRows(string filename)
{
    Cell **cellObject;
    const int row = 9;
    const int column = 9;
    cellObject = new Cell*[9];

    for (int i = 0; i < 9; ++i)
    {       
        cellObject[i] = new Cell[9];
        for (int j = 0; j < 9; ++j)
        {                           
            cout << &cellObject[i][j] << endl;                          
        }
    }
}



int main()
{
    PopulateRows("sudoku_puzzle.txt");
    cout << "\n\nPlease enter a key to exit..." << endl;
    cin.get();
    return 0;
}

Now the above code will compile and work and will display the memory addresses for each of the cellObjects, but I want to be able to read in a sudoku puzzle, named "sudoku_puzzle.txt" and then display its contents in a 9x9 grid fashion.

Can anyone possibly point me in the right direction or even show me how?

Was it helpful?

Solution

First, since the input is line oriented, I'd use std::getline for each line. The traditional approach after that would be to use std::istringstream to parse the values in the line, but for something this simple (where each digit has a fixed location, and the actual values are only a single digit), it's probably just as simple to extract the values directly from the string: character - '0' for the respective character. (Output is similar: cellValue + '0', inserting additional spaces where necessary.)

I'd also forgo the Cell class, and simply use an std::vector<int> grid(81); for the entire grid. It's probably easier to keep all of the relevant information in a Grid class. This depends, and both solutions are viable. But I certainly wouldn't keep row, column and block in Cell, since they aren't characteristics of the cell, but rather of where it is placed in the grid. And I wouldn't keep candidateList in the cell either: at any given moment, the cell has only one value, and the candidate list is only relevant for the cell(s) you're currently looking at, and is best implemented as a local variable.

OTHER TIPS

Result:

.  3  .  |  .  .  1  |  .  7  .
         |           |
6  .  .  |  8  .  .  |  .  .  2
         |           |
.  .  1  |  .  4  .  |  5  .  .
         |           |
--------- ----------- ---------
         |           |
.  7  .  |  .  .  2  |  .  4  .
         |           |
2  .  .  |  .  9  .  |  .  .  6
         |           |
.  4  .  |  3  .  .  |  .  1  .
         |           |
--------- ----------- ---------
         |           |
.  .  5  |  .  3  .  |  4  .  .
         |           |
1  .  .  |  .  .  6  |  .  .  5
         |           |
.  2  .  |  1  .  .  |  .  3  .

Code.. The printing algorithm is from my own sudoku solver..

#include <vector>
#include <iostream>
#include <fstream>

class Puzzle
{
    private:
        unsigned short Cells[9][9];
        char BlankChar;

    public:
        Puzzle(const char* FilePath, char BlankChar = '.');

        friend std::ostream& operator << (std::ostream& os, const Puzzle& p);
};

Puzzle::Puzzle(const char* FilePath, char BlankChar) : Cells(), BlankChar(BlankChar)
{
    std::fstream fs(FilePath, std::ios::in);
    if (fs.is_open())
    {
        for (int i = 0; i < 9; ++i)
        {
            for (int j = 0; j < 9; ++j)
            {
                fs >> Cells[j][i];
            }
        }
        fs.close();
    }
}

std::ostream& operator << (std::ostream &os, const Puzzle &p)
{
    for (int I = 0; I < 9; ++I)
    {
        for (int J = 0; J < 9; ++J)
        {
            if (J == 3 || J == 6)
            {
                os << "|  ";
            }

            if (p.Cells[J][I] == 0)
                os << p.BlankChar << "  ";
            else
                os << p.Cells[J][I] << "  ";
        }

        os << "\n";
        if (I != 8)
        {
            os << "\t |\t     |\n";
        }

        if (I == 2 || I == 5)
        {
            os << "--------- ----------- ---------";
            os << "\n";
            os << "\t |\t     |\n";
        }
    }
    return os;
}

int main()
{
    std::cout << Puzzle("sudoku_puzzle.txt");
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top