Ultimate tic tac toe is a fun and strategic twist on the game we all know and love. Play with your friends or hone your skills against the computer. Learn the rules » Local Game. Play against the AI or with a friend using the same device. Become a mastermind with Ultimate Tic Tac Toe. Far more complex than the original Tic Tac Toe, this upgraded version will push your brain to its limits. This strategic game will present its player nine 3x3 grids. The first player to complete 3 aligned successful grids will win. Packed with 4 diff.
This will not be a full review of the code at all since I don't really review how it works, but here are some little things that may be of interest to make it better anyway:) Qt5 new connection syntaxQt5 introduces a which allows you to directly pass function pointers instead of relying on the Qt preprocessor to do the job. Your set of connections could be rewritten as: connect(options, &Dialog::choosen,this, MainWindow::begin);connect(game, &TicTacToe::humanMoves,this, &MainWindow::humanMoves);connect(game, &TicTacToe::computerMove,this, &MainWindow::computerMove);connect(game, &TicTacToe::prediction,this, &MainWindow::prediction);There are many pros and some cons. You can look at the page I linked above for the details. Basically, the syntax is considered more compliated, but it gets typedefs and namespaces right since it does rely on the C type system and not on strings processing anymore. Moreover, the functions passed as slots don't even have to be slots anymmore; you can even pass lambdas as slots. Use nullptrSince you are using C11, you should use nullptr instead of 0 and NULL to represent null pointers.
It has the advantage of be being easy to search and to chose the pointer overload when a function is overloaded for integers and pointers: explicit MainWindow(QWidget.parent = nullptr);Don't useWhile easy to use, std::rand is not the best tool to generate random numbers. For a simple game like this, it may not matter that much, but the C11 header provides better alternatives to generate pseudo-random numbers. That's not critical for your application, but you should have a look at it. Use the free functions and std::endOnce again it won't change anything for you, but since C11, it is good practice to use the free functions std::begin and std::end instead of the container's methods.
The reason if that they will also work with C-style arrays and std::valarray. This is a good habit to take, because it ensures that your code will still work if you change the container. Of course, the real advantage of these functions is that they make template code more generic.
Std::fill(std::begin(boards),std::end(boards),std::vector(NUMSQUARES,EMPTY));begin is a half-reserved method nameWhile it is ok to name a method begin, a regular C user will expect that method to return an iterator and also will expect that another method named end, also returning an iterator, exists. There are no rules anywhere saying that this method name is reserved, but it is so commonly used for iteration that in practice it totally feels like a reserved name. To avoid a potential ambiguity, I would change the name begin to start or some equivalent in your class. That may help you or others to avoid some problems in the future. Reorganize your includesWhenever possible, incude the heades you need in the implementation file and not in the header. Also, try to remove the headers that are not used:. Move to tictactoe.cpp.
Move to MainWIndow.cpp. Remove, you don't need it. I probably forgot some more headers that you could move/delete. Try to see whether you could use forward declarations to reduce the number of headers included in the.h file. C11 in-class initializers are great, but initializing the variables in the constructors in the.cpp instead may allow you to only need forward declarations in the.h and to subsequently move of the includes to the.cpp files.