Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking for a match in each element of a 2d vector

I'm creating text based TicTacToe in C++ and need to create a function that checks for a win.

Right now, I have a vector of all the moves player X has made:

std::vector<int> x_vector = {1, 2, 3, 5, 7};

I also have a 2d vector of win conditions:

std::vector<std::vector> > wins = {{1, 2, 3}, {4, 5, 6}, {7, 8, 8}};

In this case, each element of the wins vector represents a win condition. If player X ever has a combination of inputs in their vector that includes one of the win conditions, I'm trying to get a bool function to return true.

I'm new to C++ and coding in general, so all patience is appreciated, and the simpler the solution you can help me find the better.

like image 511
Max Waters Avatar asked Dec 16 '25 21:12

Max Waters


1 Answers

You can iterate through your list of known wins, checking each to see if it is a subset of the list of user's moves. The std::includes function will do this test – but note that the two 'lists' need to be sorted.

To avoid having to manually sort the list of user's moves after each input, you can use the std::set container (which is inherently sorted), instead of std::vector.

The following snippet shows a relatively simple implementation of an isWin() function using this approach, along with some rudimentary test cases:

#include <iostream>
#include <vector>
#include <set>
#include <algorithm> // For std::includes

bool isWin(const std::set<int>& test)
{
    static std::vector<std::set<int>> winlist = { 
        {1, 2, 3}, {4, 5, 6}, {7, 8, 9},    // Horizontal lines
        {1, 4, 7}, {2, 5, 8}, {3, 6, 9},    // Vertical lines
        {1, 5, 9}, {3, 5, 7},               // Diagonal lines
    };

    for (auto win : winlist) {
        if (std::includes(test.begin(), test.end(), win.begin(), win.end()))  {
            return true; // Match - Win!
        }
    }
    return false; // Didn't get a match - no win
}

int main()
{
    std::set<int> s1{ 1, 2 }; // Trivial "No win" (only 2 moves)
    std::cout << "s1: " << isWin(s1) << "\n";

    std::set<int> s2{ 1, 2, 3 }; // Trivial "Win" (top row)
    std::cout << "s2: " << isWin(s2) << "\n";

    std::set<int> s3{ 2, 4, 1, 5 }; // " No Win"
    std::cout << "s3: " << isWin(s3) << "\n";

    std::set<int> s4{ 5, 2, 4, 6 }; // "Win" (middle row)
    std::cout << "s4: " << isWin(s4) << "\n";

    std::set<int> s5{ 5, 1, 3, 6, 9 }; // "Win" (diagonal)
    std::cout << "s5: " << isWin(s5) << "\n";

    return 0;
}

Note that this approach may not be the best for checking wins in a Tic-Tac-Toe game; however, if your purpose is to learn about vectors, sets and looking for matching sub-sequences, it may provide a useful starting-point.


For your actual user input, you would declare and initialize an empty set and then add moves using the insert member function of the std::set container class; something like this:

int main()
{
    std::set<int> user{}; // Empty Set
    user.insert(5);
    user.insert(2);
    user.insert(4);
    user.insert(6);
    std::cout << "user (1): " << isWin(user) << "\n";
    user.clear();
    user.insert(2);
    user.insert(4);
    user.insert(1);
    user.insert(5);
    std::cout << "user (2): " << isWin(user) << "\n";
    return 0;
}
like image 90
Adrian Mole Avatar answered Dec 19 '25 11:12

Adrian Mole



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!