Public Group

# So I finished my Tic-Tac-Toe game but...

This topic is 3853 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm sure I can program it a lot more efficiently then I did. I'm fairly new at C++ and here's my Tic-Tac-Toe:
#include <iostream>
using namespace std;

char map[3][3];
bool xTurn, yTurn;
bool GameOver = false;
int turnsTaken = 0;

/*class X
{
public:
X(int x, int y){}
~X();
int locX, locY;
};

class Y
{
public:
Y(int x, int y) {}
~Y();
int locX, locY;
};*/

void DisplayMap()
{
int xs, ys;
cout << "Map:\n";
for (xs = 0; xs<3; xs++)
{
for(ys = 0; ys<3; ys++)
{
cout << "[" << xs << "][" << ys << "] ";
cout <<  map[xs][ys] << " ";
if(ys == 2) cout << "\n";
if(ys == 2 && xs == 2) cout << "\n\n";
}
}
/*
for (xs = 0; xs<3; xs++)
{
for(ys = 0; ys<3; ys++)
{
cout << "[" << xs << "][" << ys << "] ";
if(ys == 2) cout << "\n";
if(ys == 2 && xs == 2) cout << "\n\n";
}
}*/
}

void CheckMap()
{
if(xTurn)
{
if(map[0][0] == 'X' && map[0][1] == 'X' && map[0][2] == 'X')
{
cout << "X wins!\n\n";
GameOver = true;
}
else if(map[1][0] == 'X' && map[1][1] == 'X' && map[1][2] == 'X')
{
cout << "X wins!\n\n";
GameOver = true;
}
else if(map[2][0] == 'X' && map[2][1] == 'X' && map[2][2] == 'X')
{
cout << "X wins!\n\n";
GameOver = true;
}
else if(map[0][0] == 'X' && map[1][0] == 'X' && map[2][0] == 'X')
{
cout << "X wins!\n\n";
GameOver = true;
}
else if(map[0][1] == 'X' && map[1][1] == 'X' && map[2][1] == 'X')
{
cout << "X wins!\n\n";
GameOver = true;
}
else if(map[0][2] == 'X' && map[1][2] == 'X' && map[2][2] == 'X')
{
cout << "X wins!\n\n";
GameOver = true;
}
else if(map[0][0] == 'X' && map[1][1] == 'X' && map[2][2] == 'X')
{
cout << "X wins!\n\n";
GameOver = true;
}
else if(map[0][2] == 'X' && map[1][1] == 'X' && map[2][0] == 'X')
{
cout << "X wins!\n\n";
GameOver = true;
}
}

else if(yTurn)
{
if(map[0][0] == 'Y' && map[0][1] == 'Y' && map[0][2] == 'Y')
{
cout << "Y wins!\n\n";
GameOver = true;
}
else if(map[1][0] == 'Y' && map[1][1] == 'Y' && map[1][2] == 'Y')
{
cout << "Y wins!\n\n";
GameOver = true;
}
else if(map[2][0] == 'Y' && map[2][1] == 'Y' && map[2][2] == 'Y')
{
cout << "Y wins!\n\n";
GameOver = true;
}
else if(map[0][0] == 'Y' && map[1][0] == 'Y' && map[2][0] == 'Y')
{
cout << "Y wins!\n\n";
GameOver = true;
}
else if(map[0][1] == 'Y' && map[1][1] == 'Y' && map[2][1] == 'Y')
{
cout << "Y wins!\n\n";
GameOver = true;
}
else if(map[0][2] == 'Y' && map[1][2] == 'Y' && map[2][2] == 'Y')
{
cout << "Y wins!\n\n";
GameOver = true;
}
else if(map[0][0] == 'Y' && map[1][1] == 'Y' && map[2][2] == 'Y')
{
cout << "Y wins!\n\n";
GameOver = true;
}
else if(map[0][2] == 'Y' && map[1][1] == 'Y' && map[2][0] == 'Y')
{
cout << "Y wins!\n\n";
GameOver = true;
}
}

}

void GameLoop()
{
if(xTurn)
{
cout << "It is player X's turn.\n";
DisplayMap();
bool xPlaced = false;
int placingX, placingY;
while(!xPlaced)
{
cout << "Which X coordinate would you like to place your X? ";
cin >> placingX;
cout << "Which Y coordinate would you like to place your X? ";
cin >> placingY;
if(map[placingX][placingY] == '-')
map[placingX][placingY] = 'X';
cout << "\n\n";
xPlaced = true;
}
CheckMap();
if(!GameOver)
{
xPlaced = false;
xTurn = false;
yTurn = true;
GameLoop();
}
}
else if(yTurn)
{
cout << "It is player Y's turn.\n";
DisplayMap();
bool yPlaced = false;
int placingX, placingY;
while(!yPlaced)
{
cout << "Which X coordinate would you like to place your Y? ";
cin >> placingX;
cout << "Which Y coordinate would you like to place your Y? ";
cin >> placingY;
if(map[placingX][placingY] == '-')
map[placingX][placingY] = 'Y';
cout << "\n\n";
yPlaced = true;
}
CheckMap();
if(!GameOver)
{

yPlaced = false;
yTurn = false;
xTurn = true;
turnsTaken++;
if(turnsTaken >= 9)
cout << "Cat's game! No one wins.";
else
GameLoop();
}
}
}

int main()
{
cout << "\t\tWelcome to Dession's Tic-Tac-Toe three in a row!\n\n";
xTurn = true;
char blank = '-';
map[0][0] = blank;
map[0][1] = blank;
map[0][2] = blank;
map[1][0] = blank;
map[1][1] = blank;
map[1][2] = blank;
map[2][0] = blank;
map[2][1] = blank;
map[2][2] = blank;
GameLoop();
system("pause");
return 0;
}


What are some better ways to accomplish what I have done in this program? I'm trying to learn better habbits and get better with C++. Thank you!

##### Share on other sites
First off, congratulations on finishing your first game.

The first step to making your code better is to identify repetition of code and remove it. The main offender of this in your code, is the CheckMap() function.

Notice how you have almost identical code for checking for a win for X as for a win for Y. You could easily condense this using the following:

// First line of CheckMap()char turn = (xTurn ? 'X' : 'Y'); // The current player's turn

Then replace

if(map[0][0] == 'X' && map[0][1] == 'X' && map[0][2] == 'X')	{		cout << "X wins!\n\n";		GameOver = true;  	}	// ... etc.

with

if(map[0][0] == turn && map[0][1] == turn && map[0][2] == turn)	{		cout << turn << " wins!\n\n";		GameOver = true;  	}	// ... etc.

You can do a similar thing in your main game loop, as it has almost the same repetition with the same logic but for different players.

You also repeat the code below many times:

cout << turn << " wins!\n\n";GameOver = true;

You should combine all the if-statements into one big one that shares the result. Your new CheckMap() function would look like this:

void CheckMap(){	char turn = (xTurn ? 'X' : 'Y');	if(	(map[0][0] == turn && map[0][1] == turn && map[0][2] == turn) ||		(map[1][0] == turn && map[1][1] == turn && map[1][2] == turn) ||		(map[2][0] == turn && map[2][1] == turn && map[2][2] == turn) ||		(map[0][0] == turn && map[1][0] == turn && map[2][0] == turn) ||		(map[0][1] == turn && map[1][1] == turn && map[2][1] == turn) ||		(map[0][2] == turn && map[1][2] == turn && map[2][2] == turn) ||		(map[0][0] == turn && map[1][1] == turn && map[2][2] == turn) ||		(map[0][2] == turn && map[1][1] == turn && map[2][0] == turn) )	{		cout << turn << " wins!\n\n";		GameOver = true;  	}}

Alternatively, you could use a loop to check for each row, each column and then check for diagonals, but imo it wouldn't really be any more elegant.

Some other things:

- Use STL vectors instead of arrays.
- Check user input to make sure it is valid.
- Avoid global variables eg. GameOver should simply be a return value from CheckMap()

##### Share on other sites
This is how id doo it

void CheckMap(){	char turn = 'Y';        if (xTurn) turn = 'X';//Post above does this better, just showing how i would do it        for (loop=0;loop<3;loop++)        {	if((map[loop][0] == turn && map[loop][1] == turn && map[loop][2] == turn) ||	(map[0][loop] == turn && map[1][loop] == turn && map[2][loop] == turn))	{		cout << turn << " wins!\n\n";		GameOver = true;  	}}

Also rather than have xTurn and yTurn id have an int Turn
Turn=0 (X's turn)
Turn=1 (Y's turn)

Swap turn:

Turn=!Turn;

Also in the game loop the same code is used twice for X and Y. Consider this alternative (using the Turn idea above)

const char PlayerIDs[2]={'X','Y'};

now you can say (e.g) "It is " << PlayerIds[Turn] << " turn to play"
and input into the map using the array as well.

##### Share on other sites
Well done for finishing!
Well done for not giving up!
Well done for wanting to improve it and your skills!

Onto improvements then.

Globals
The first thing to note is that global variables aren't good practice. Instead you ought to make use of parameters to pass these around.

Having taken a look at the global variables you have there, you have both xTurn and yTurn, now clearly only one player gets to move at once. So it would make more sense to have only one variable, say: xTurn, and if this is true then it's player X to move, if it's false then it's player Y to move.

DisplayMap
Your code inside the DisplayMap function needlessly performs two checks to determine when to place spaces.
A better implementation would be:
void DisplayMap(){     cout << "Map:\n";      for (int x = 0; x < 3; x++)     {         for(int y = 0; y < 3; y++)         {                cout << "[" << xs << "][" << ys << "] "                cout <<  map[xs][ys] << " ";         }         cout << "\n";     }     cout << "\n\n";}

This obviously still ignores the fact that globals are bad, it also ignores the fact that hard-coded magic numbers (like x < 3) aren't good practice either.
Somewhere, it'd be better to have something like: static const int WIDTH = 3;
Or, ideally, you'd be using std::vector which keeps track of it's size for you, but we'll get to that.

..aren't really loops at all. Look closely at how you've set them up...
Something similar to this:
bool xPlaced = false;while(!xPlaced){    /*        Doing stuff here    */    xPlaced = true;}

A piece of code like this is only ever going to be executed once.
What's worse is it means that if the player chose a coordinate that is already occupied then they effectively forefit their go, your code will correctly not overwrite the position but it won't ask them to enter it again!
A minor edit to if statement in the code fixes all this:
while(!xPlaced){    cout << "Which X coordinate would you like to place your X? ";    cin >> placingX;    cout << "Which Y coordinate would you like to place your X? ";                                  cin >> placingY;    if(map[placingX][placingY] == '-')    {        map[placingX][placingY] = 'X';        cout << "\n\n";        xPlaced = true;    }}

Now it will only leave the while-loop when the player enters a valid coordinate and it will keep asking them for the coordinate if their location is already occupied. You should probably add an else block to tell them what they've done wrong, I'll leave that as a simple exercise.

You could actually use a do..while() loop instead of a while() loop, but that's neither here nor there really.

CheckMap
Consider this, in your code you have this code snippet:
CheckMap();
if(!GameOver)

Now, suppose you make the following changes:
• Rename CheckMap to IsGameWon
• Implement IsGameWon as (modifying Poita's version):
bool IsGameWon(){	char turn = (xTurn ? 'X' : 'Y');	return(	(map[0][0] == turn && map[0][1] == turn && map[0][2] == turn) ||		(map[1][0] == turn && map[1][1] == turn && map[1][2] == turn) ||		(map[2][0] == turn && map[2][1] == turn && map[2][2] == turn) ||		(map[0][0] == turn && map[1][0] == turn && map[2][0] == turn) ||		(map[0][1] == turn && map[1][1] == turn && map[2][1] == turn) ||		(map[0][2] == turn && map[1][2] == turn && map[2][2] == turn) ||		(map[0][0] == turn && map[1][1] == turn && map[2][2] == turn) ||		(map[0][2] == turn && map[1][1] == turn && map[2][0] == turn) );}
(I'm still ignoring that globals are bad etc etc).

Then you can now check for a player winning as:
if( IsGameWon() )

And check that the game is still in-play as:
if( !IsGameWon() )

GameLoop
So , in the GameLoop function, you're checking whether the game is over in two different places, you're basically doing this:
If X's turn{    make X move    If game still playing        call GameLoop    Else        player X wins}Else if Y's turn{    make Y move    If game still playing        call GameLoop    Else if player Y wins        player Y wins    Else if draw        its a draw}
That's quite complicated, a more sensible arrangement might be:
loop until gameover{    If X's turn        make X move    else        make Y move}If a win    player(X|Y) winsElse    its a draw
So how would that look? Well something like:
void GameLoop(){    bool xTurn = false;    int turnCount = 0;    // Loop until gameover, 9 ought to be WIDTH*HEIGHT    while(turnCount < 9 && !IsGameWon())    {        // Incremement the turnCount and alternate the next player        turnCount++;        xTurn = !xTurn;        if(xTurn)        {            cout << "It is player X's turn.\n";            DisplayMap();            bool xPlaced = false;            while(!xPlaced)            {                int placingX, placingY;                cout << "Which X coordinate would you like to place your X? ";                cin >> placingX;                cout << "Which Y coordinate would you like to place your X? ";                cin >> placingY;                if(map[placingX][placingY] == '-')                {                    map[placingX][placingY] = 'X';                    cout << "\n\n";                    xPlaced = true;                }            }        }        else        {            cout << "It is player Y's turn.\n";            DisplayMap();            bool yPlaced = false;            while(!yPlaced)            {                int placingX, placingY;                cout << "Which X coordinate would you like to place your Y? ";                cin >> placingX;                cout << "Which Y coordinate would you like to place your Y? ";                cin >> placingY;                if(map[placingX][placingY] == '-')                {                    map[placingX][placingY] = 'Y';                    cout << "\n\n";                    yPlaced = true;                }            }        }    }    // Game is over, test if it was a win or a draw    if( turnCount < 9 )    {        // It's a win        cout << (xTurn ? 'X' : 'Y') << " Wins!\n\n";    }    else    {        // It's a draw        cout << "Cat's game! No one wins.";    }}

Back to those while loops
You'll have noticed I'm sure that those while loops are very similar to each other with only minor changes. This hints that you can probably refactor that code out into its own function, and indeed you can:
void MakeMove(char piece){    int placingX, placingY;    bool isPlaced = false;    while(!isPlaced)    {        cout << "Which X coordinate would you like to place your " << piece << "? ";        cin >> placingX;        cout << "Which Y coordinate would you like to place your " << piece << "? ";        cin >> placingY;        if(map[placingX][placingY] == '-')        {            map[placingX][placingY] = piece;            cout << "\n\n";            isPlaced = true;        }    }}

Now GameLoop becomes much more intuitive:
void GameLoop(){    bool xTurn = false;    int turnCount = 0;        // Loop until gameover, 9 ought to be width*height    while(turnCount < 9 && !IsGameWon())    {        // Incremement the turnCount and alternate the next player        turnCount++;        xTurn = !xTurn;        if(xTurn)        {            cout << "It is player X's turn.\n";            DisplayMap();            MakeMove('X');        }        else        {            cout << "It is player Y's turn.\n";            DisplayMap();            MakeMove('Y');        }    }    // Game is over, test if it was a win or a draw    if( turnCount < 9 )    {        // It's a win        cout << (xTurn ? 'X' : 'Y') << " Wins!\n\n";    }    else    {        // It's a draw        cout << "Cat's game! No one wins.";    }}

So what's left?
The rest I'm not going to demonstrate, but things that you could/should consider:
• It's arguable whether it's worth it in this instance, however in the general case you should be using std::vector for arrays. There are loads of tutorials about how to use them, and how to use them for 2-dimensional arrays (though you can access a 1-dimensional array like as if it's a 2-dimensional array!).

• Don't use globals, I'm re-iterating this point. The correct method is to pass them as parameters into your functions.

• Don't use magic numbers, it's easy to do but they're a royal pain when you forget what they stood for. Instead assign them to constants and use those constants in their place. e.g. static const int GRID_WIDTH = 3;
It also means you can easily change the value at a later date without needing to sift all through you code looking for every place you put that number.

• You could use this as an easy first step into Object Oriented Design (OOD) and Object Oriented Programming (OOP). If you think about it the main bulk of your code revolves around the idea of a board. You could have a class called Board which is responsible for managing the state of the playing board. It would expose an interface that lets you interact with the board to perform certain operations like placing a piece.
Such a class might look like this:
class Board{public:    Board();                      // The constructor initialises a board with '-'    void display();               // This will display the board    bool checkForWin(bool xTurn); // This will check if there is 3 in a row    bool placePiece(bool xTurn);  // This will try to place a piece and return whether it was successfulprivate:    std::vector< std::vector<char> > grid; // A 2D vector array    // Alternatively to the above line you can use a single vector of    // size 3*3 = 9 and just cleverly access those elements, its    // slightly more efficient};

You might also want a couple of methods (or public constants) to indicate the dimensions of the board.

Well there you go, I hope that was of some help [smile]
I should point out (disclaimer style) that none of my code is tested and as such may be non-compilable and may contain typos, minor bugs, explicit content, nuts and dairy products.

Good luck

##### Share on other sites
Wow, you guys. Go on and leave me with nothing to say, eh? :)

Actually, I do have something to say: Grab yourself a version control system and learn to use it. Don't leave commented-out source lying around your code; it's messy and in the long run will tend to confuse you.

Also, don't think in terms of "efficient" - yet. Think in terms of "neat". Efficiency is largely a matter of not doing blatantly useless things, and even then it often doesn't matter. Eliminating duplication from your code will usually not make a noticeable difference to performance (either way) - not that performance really matters for a program that will spend 99.9999% of its time waiting for the user to make up his mind. But it will make it (a) easier to fix things in the future (or add more features), (b) easier to read, and (c) easier to verify; and it often (d) fixes bugs you didn't realize were there (because there's no way for multiple versions of the code to be slightly inconsistent with each other if there are not, in fact, multiple versions of the code).

##### Share on other sites
Thanks for all the help guys, I implented all of your suggestions and came out with:

#include <iostream>using namespace std;static const int MAP_WIDTH = 3;static const int MAP_HEIGHT = 3;char map[MAP_WIDTH][MAP_HEIGHT];bool xTurn = false;void DisplayMap(){     int xs, ys;     cout << "Map:\n";      for (xs = 0; xs<MAP_WIDTH; xs++)     {         for(ys = 0; ys<MAP_HEIGHT; ys++)         {                cout << "[" << xs << "][" << ys << "] ";                cout <<  map[xs][ys] << " ";         }         cout << "\n";     }     cout << "\n\n";}bool IsGameWon(){	char turn = (xTurn ? 'X' : 'Y');	return(	(map[0][0] == turn && map[0][1] == turn && map[0][2] == turn) ||		(map[1][0] == turn && map[1][1] == turn && map[1][2] == turn) ||		(map[2][0] == turn && map[2][1] == turn && map[2][2] == turn) ||		(map[0][0] == turn && map[1][0] == turn && map[2][0] == turn) ||		(map[0][1] == turn && map[1][1] == turn && map[2][1] == turn) ||		(map[0][2] == turn && map[1][2] == turn && map[2][2] == turn) ||		(map[0][0] == turn && map[1][1] == turn && map[2][2] == turn) ||		(map[0][2] == turn && map[1][1] == turn && map[2][0] == turn) );}void MakeMove(char piece){    int placingX, placingY;    bool isPlaced = false;    while(!isPlaced)    {        cout << "Which X coordinate would you like to place your " << piece << "? [0-2]\n";        cin >> placingX;        cout << "Which Y coordinate would you like to place your " << piece << "? [0-2]\n";        cin >> placingY;                if(placingX > 2 || placingX <0 || placingY > 2 || placingY < 0 || map[placingX][placingY] != '-')                    cout << "\nYou can't place your " << piece << " at that location! Try again.\n\n";        else if(map[placingX][placingY] == '-')        {            map[placingX][placingY] = piece;            cout << "\n\n";            isPlaced = true;        }    }}void GameLoop(){    int turnCount = 0;        while(turnCount < MAP_HEIGHT*MAP_WIDTH && !IsGameWon())    {        // Incremement the turnCount and alternate the next player        turnCount++;        xTurn = !xTurn;        if(xTurn)        {            cout << "It is player X's turn.\n";            DisplayMap();            MakeMove('X');        }        else        {            cout << "It is player Y's turn.\n";            DisplayMap();            MakeMove('Y');        }    }    // Game is over, test if it was a win or a draw    if( turnCount < MAP_HEIGHT*MAP_WIDTH )    {        // It's a win        cout << (xTurn ? 'X' : 'Y') << " Wins!\n\n";        DisplayMap();    }    else    {        // It's a draw        cout << "Cat's game! No one wins.\n\n";        DisplayMap();    }}int main(){    cout << "\t\tWelcome to Dession's Tic-Tac-Toe three in a row!\n\n";    int xs, ys;    for (xs = 0; xs<MAP_WIDTH; xs++)    {        for(ys = 0; ys<MAP_HEIGHT; ys++)        {               map[xs][ys] = '-';        }    }      GameLoop();    system("pause");    return 0;}

Quote:
 Original post by ZahlmanActually, I do have something to say: Grab yourself a version control system and learn to use it.

What is a version control system? =P

P.S. I'll work on using vectors and OOP, I'll rewrite the game and see how it goes!

[Edited by - Dession on January 3, 2008 3:37:40 PM]

##### Share on other sites
Quote:
 Original post by DessionWhat is a version control system?

A good phrase to plug in to [google]. But to save you some part of the effort: assuming you're on Windows, I strongly recommend the TortoiseSVN shell extension.

Quote:
 P.S. I'll work on using vectors and OOP, I'll rewrite the game and see how it goes!

1) You don't really need a vector for a tic-tac-toe board; it doesn't buy you anything because you know the size. (Also, using a vector will force you to do extra work to create the abstraction - there are a couple of different ways, but it's still work - of a rectangular "grid".)

2) Don't rewrite; refactor. I.e., keep changing things in the way you changed your original code to get the current code. Except, make one change at a time and test them.

##### Share on other sites

int winpos[] = {0,1,2, 3,4,5, 6,7,8, 0,3,6, 1,4,7, 2,5,8, 0,4,8, 2,4,6};bool IsGameWon(){    char turn = (xTurn ? 'X' : 'Y');    char *m = map[0];    for (int i = 0; i < 24; i += 3)        if (m[winpos[i+0]] == turn         && m[winpos[i+1]] == turn         && m[winpos[i+2]] == turn)            return true;    return false;}

I just installed Visual C++ 2008 express and changed the type of m. Now it compiles and works :)

[Edited by - DevFred on January 3, 2008 5:22:33 PM]

##### Share on other sites
Quote:
 Original post by DessionI'll work on using [...] OOP

You could make a class for the Map. Look at the following code:

#include <iostream>using namespace std;int winpos[] = {0,1,2, 3,4,5, 6,7,8, 0,3,6, 1,4,7, 2,5,8, 0,4,8, 2,4,6};class Map{private:	char map[3][3];	int count;public:	Map() : count(0)	{		for (int i=0; i<9; ++i)			map[0] = '-';	}	void display()	{		for (int xs = 0; xs<3; ++xs)		{			for(int ys = 0; ys<3; ys++)			{				cout << "[" << xs << "][" << ys << "] ";				cout << map[xs][ys] << " ";			}			cout << "\n";		}		cout << "\n\n";	}	bool wins(char piece)	{		char *m = map[0];		for (int i = 0; i < 24; i += 3)			if (m[winpos[i+0]] == piece			 && m[winpos[i+1]] == piece			 && m[winpos[i+2]] == piece)				return true;		return false;	}	bool validMove(int xs, int ys)	{		return xs >=0 && xs < 3 && ys >= 0 && ys < 3 && map[xs][ys] == '-';	}	void makeMove(int xs, int ys, char piece)	{		map[xs][ys] = piece;		++count;	}	bool full()	{		return count == 9;	}};Map map;char piece = 'Y';void makeMove(){    int placingX, placingY;    while (true)    {		cout << "Which X coordinate would you like to place your " << piece << "? [0-2]\n";		cin >> placingX;		cout << "Which Y coordinate would you like to place your " << piece << "? [0-2]\n";		cin >> placingY;		if (map.validMove(placingX, placingY)) break;		cout << "\nYou can't place your " << piece << " at that location! Try again.\n\n";	}	map.makeMove(placingX, placingY, piece);}int main(){	cout << "\t\tWelcome to Dession's Tic-Tac-Toe three in a row!\n\n";	map.display();	while(true)	{		piece = piece ^ 1;		cout << "It is player " << piece << "'s turn.\n";		makeMove();		map.display();		if (map.wins(piece))		{			cout << piece << " wins!\n\n";			break;		}		else if (map.full())		{			cout << "Cat's game! No one wins.\n\n";			break;		}    }    system("pause");    return 0;}

##### Share on other sites
empirical2, your CheckMap() doesn't check for diagonals.

1. 1
2. 2
3. 3
Rutin
19
4. 4
5. 5

• 10
• 14
• 30
• 13
• 11
• ### Forum Statistics

• Total Topics
631785
• Total Posts
3002348
×