简体   繁体   中英

C++ how to check if each row and column of 3x3 matrix contains only different numbers

In my Hitori game, the player removes numbers from the gameboard.

The game is won if all rows and columns have only different numbers.

In line 43, I would need to make some check function so that the board is checked after every removal, but I dont know how to do that. Should I perhaps make several for-loops?

#include <iostream>
#include <vector>
#include <string>
#include <sstream>

using namespace std; using Board = std::vector<vector<int>>;
const unsigned char EMPTY = ' ';

void initBoard(Board& board) {

string input = "1 1 3 1 2 2 2 2 3";

istringstream is { input };

    for (auto& row : board)
    {
        for(auto& column : row)
        {
        is >> column;
        }
    }
}

void printBoard(const Board& board) {


    for(unsigned int row = 0; row < 3; ++row)
    {
       cout << "| " << row + 1 << " | ";
        for(unsigned int column = 0; column < 3; ++column)
        {
            if(board.at(row).at(column) == 0)
            {
                cout << EMPTY << " ";
            }
            else
            {
                cout << board.at(row).at(column) << " ";
            }
        }
       cout << "|" << endl;
    }
    // CHECK IF EACH ROW AND COLUMN CONTAIN THE SAME NUMBER SEVERAL TIMES
    // IF NOT -> THE GAME HAS BEEN WON

}

void updateBoard(Board& board) {

    int x, y;

    while (true) {
        cout << "Enter coordinates (x, y): ";
        cin >> x;
        cin >> y;

            board.at(y-1).at(x-1) = 0;
            printBoard(board);
}
}

int main()
{
    Board board(3, vector<int>(3)); // board is vector with 3 rows and 3 columns
    initBoard(board);
    printBoard(board);
    updateBoard(board);
}

You need something that can be used to count how often a value occurs in a row or column. Because your values are nonnegative integers, you can use them as the indices of an array or vector, as suggested by Pete Becker. Another way is to use them as the keys of an associative container like std::unordered_map .

My preference would be to put these checks in separate function(s) that you call from within the game loop, so that it can terminate when a win is detected. Here is an example function that checks the columns of the board, returning true if each has unique values:

#include <algorithm>
#include <unordered_map>

using RepCount = std::unordered_map<int, int>;

bool allUnique(RepCount const& reps)
{
    return std::ranges::all_of(reps, [](auto& pair) {
        auto [value, count] = pair;
        return value == 0 || value == EMPTY || count == 1;
    });
}

bool checkColumns(Board const& board)
{
    for (unsigned col = 0; col < 3; ++col) {
        RepCount reps;
        for (auto& row : board)
            ++reps[row[col]];
        if (!allUnique(reps))
            return false;
    }
    return true;
}

You can invert this loop to perform the same check for each row.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM