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?

Était-ce utile?

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

Autres conseils

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");
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top