Hello, I am trying to produce a Tic Tac Toe problem that puts the user against the computer. This is the (probably inefficient) code that I have right now. There are two significant problems:
1. When I input field '7' it automatically says, "You win."
2. The Mersenne Twister generator that is supposed to generate a random number between 1 and 9 does not seem to work properly. It seems like the only number that it produces is the number 6. What is going on?
Please let me know what do vis-a-vis the above, and also if you have any optimization suggestions. Thank you in advance!
When one represents a 2d array as a 1d array, there is a formula: row * NumCols + col. So this works when rows and cols are numbered in the normal C/C++ fashion: 0 to 2. In the 1d array runs from 0 to 8. You could adjust your numbering system to suit this, or subtract 1 from the user input. So one can do the reverse of this - work out the row and col given a number from 0 to 8. Use integer division and the modulus. And the point of all this is so you can have one function instead of 9 repetitions of lines 62 to 80 :+)
To check for a win, consider maintaining a sum of each column, row and both diagonals. If the sum of a row equals 3 * the value for an X then that is a win. So then you could have:
Perhaps you should increase your compiler warning level, or fix the warnings your compiler is generating?
In function 'void GeneralInput(int)': 70:28: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 75:34: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 89:28: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 94:33: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 108:28: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 113:33: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 127:28: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 132:33: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 146:28: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 151:33: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 165:28: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 170:33: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 184:28: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 189:33: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 203:28: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 208:33: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 222:28: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 227:33: warning: suggest parentheses around assignment used as truth value [-Wparentheses] In function 'char HowToWin()': 349:1: warning: control reaches end of non-void function [-Wreturn-type]
I fixed Problem 1 by adding "return '/';" right before the termination of HowtoWin(). Very strange!
Why are you returning '/'? That doesn't look like a valid value for the logic in your CheckWin() function. By the way it's not strange, you should always insure that a function that returns a value actually returns a value.
This looks like you have some logic holes in that function, perhaps you should try to simplify the logic. You have what appears to be a lot of duplicate code, you may want to investigate using some loops.
The "only" problem now (other than obvious optimization issues) is that the Mersenne Twister random number generator in the AIinput() sometimes returns values for fields that are already taken. I tried to get around this in GeneralInput() by looping back to AIinput().
Once again, I very much appreciate all the feedback!
Just had another thought. If you made a vector of the all sums, with the first 8 for the O's (3 rows, 3 cols, 2 diag), then the next 8 for the X's , then you could use the find algorithm to search for a winning value. That way, to determine a win could be only 1 statement. Note that the values in this vector are only incremented once a O or X is placed.
Also, just to reiterate about compiler warning levels, they are your friend - they tell where problems are, so set the warning level at it's highest (or at least turn on as many warnings as are practicable). From my point of view, if I have warnings, then I am not finished.
The other concept is of code repetition, if you find yourself repeating code, or doing code that is very similar, then there is almost always a better way :+)
The "only" problem now (other than obvious optimization issues) is that the Mersenne Twister random number generator in the AIinput() sometimes returns values for fields that are already taken. I tried to get around this in GeneralInput() by looping back to AIinput().
There is a problem with the way you are generating random numbers.
251 252 253 254 255 256 257 258 259 260
void AIinput()
{
player = 'O';
mt19937 mt_rand(time(0)); // seed the generator
uniform_int_distribution<> distr(1, 9); // define the range
int n = (int)distr(mt_rand);
GeneralInput(n);
}
Above, at line 255, the generator is reseeded using the current time on every call. The generator should be seeded just once at the start of the program, and then subsequent values are generated by the mt19937 itself.
It may not seem to matter much here, because the user input may be sufficiently slow as to allow the time to change on each move. But for example if you were to get the computer to play both X and O sides of the game, the speed of play would be fast enough to cause it to be trapped by the re-seeding problem, every move would be identical - at least the first several million iterations.