Programming Forums

Programming Forums (http://www.programmingforums.org/forumindex.php)
-   C++ (http://www.programmingforums.org/forum15.html)
-   -   Tic-Tac-Toe (http://www.programmingforums.org/showthread.php?t=12218)

Disruptor Dec 19th, 2006 7:12 PM

Tic-Tac-Toe
 
Hey everyone, I知 new to this forum.

I知 sure there are countless examples of how to do a tic-tac-toe game but I知 not worried about copying and pasting code. I致e done my own little rendition of it but I知 stuck at the following spot. I知 stuck trying to figure out how the computer will react to any move other than the first and second.

Here is my code so far hopefully you guy can give me an example of what to do from here and maybe if you see something that is inefficient let me know and ill fix it.

:

  1. #include "stdafx.h"
  2.  
  3. // DRAW DEFAULT BOARD
  4. char board[3][3];
  5.  
  6. // HOW MANY MOVES
  7. int moves = 0;
  8. // WHOS TURN
  9. bool Turn;
  10.  
  11. // DRAW THE PLAYING FIELD
  12. void DrawBoard()
  13. {
  14.         // SHOW MOVES
  15.         printf("\nMove #%d\n", moves);
  16.         // DRAW TOP
  17.         printf("*************\n");
  18.         // LOOP THROUGH HEIGHT
  19.         for(int i=0;i<3;i++)
  20.         {
  21.                 // LOOP THROUGH WIDTH
  22.                 for(int j=0;j<3;j++)
  23.                 {
  24.                         // SHOW EACH POSITION
  25.                         printf("|_%c_", board[i][j]);
  26.                 }
  27.                 // ADD AN EXTRA END LINE
  28.                 printf("|\n");
  29.         }
  30.         // DRAW BOTTOM
  31.         printf("*************\n");
  32. }
  33.  
  34. // CALCULATE MOVING POSITION
  35. bool CanMove(int posX, int posY)
  36. {
  37.         // TRIGGER STARTS TRUE
  38.         bool ok = true;
  39.         // ERROR MESSAGE
  40.         char *str = "";
  41.  
  42.         // IF USER ALREADY HAS POSITION
  43.         if(board[posX][posY] == 'X')
  44.         {
  45.                 // NOT MOVEABLE
  46.                 ok = false;
  47.                 // ERROR
  48.                 if(Turn)
  49.                         str = "You already have that spot!";
  50.         }
  51.         // IF COMPUTER ALREADY HAS POSITION
  52.         else if(board[posX][posY] == 'O')
  53.         {
  54.                 // NOT MOVEABLE
  55.                 ok = false;
  56.                 // ERROR
  57.                 if(Turn)
  58.                         str = "That spot is controlled by the other player!";
  59.         }
  60.  
  61.         // SHOW ANY ERRORS
  62.         if(str != "")
  63.                 printf("%s", str);
  64.  
  65.         // RETURN THE VALUE OF OK
  66.         return ok;
  67. }
  68.  
  69. // GET USER MOVE
  70. void UserMove()
  71. {
  72.         // DECLARE POSITION VARIABLES
  73.         int posX, posY;
  74.  
  75.         // GET WIDTH
  76.         printf("\nHow many places over (0-2): ");
  77.         scanf ("%d", &posX);
  78.         // GET HEIGHT
  79.         printf("\nHow many places down (0-2): ");
  80.         scanf ("%d", &posY);
  81.  
  82.         // CAN THEY MOVE THERE?
  83.         if(CanMove(posX, posY))
  84.         {
  85.                 // USER MOVES THERE
  86.                 board[posX][posY] = 'X';
  87.                 // COMPUTERS TURN
  88.                 Turn = false;
  89.                 // MADE A MOVE
  90.                 moves++;
  91.         }
  92. }
  93.  
  94. // COMPUTERS TURN
  95. void ComputerMove()
  96. {
  97.         // IF COMPUTER GOES FIRST - MOVE TO CENTER
  98.         if(moves == 0)
  99.                 board[1][1] = 'O';
  100.         // THINK ABOUT MOVE
  101.         else if(moves == 1)
  102.         {
  103.                 // CHECK CENTER
  104.                 if(CanMove(1,1))
  105.                         board[1][1] = 'O';
  106.                 // CHECK TOP LEFT COURNER
  107.                 else if(CanMove(0,0))
  108.                         board[0][0] = 'O';
  109.                 // CHECK TOP RIGHT COURNER
  110.                 else if(CanMove(3,0))
  111.                         board[3][0] = 'O';
  112.                 // CHECK BOTTOM LEFT COURNER
  113.                 else if(CanMove(0,3))
  114.                         board[0][3] = 'O';
  115.                 // CHECK BOTTOM RIGHT COURNER
  116.                 else if(CanMove(3,3))
  117.                         board[3][3] = 'O';
  118.         }
  119.         else
  120.         {
  121.                 // TODO: Reaction to other moves
  122.         }
  123.  
  124.         // USERS TURN
  125.         Turn = true;
  126.         // MADE A MOVE
  127.         moves++;
  128. }
  129.  
  130. int _tmain(int argc, _TCHAR* argv[])
  131. {
  132.         // PLAYING
  133.         bool Playing = true;
  134.  
  135.         // FILL BOARD
  136.         for(int i=0; i<3; i++)
  137.         {
  138.                 for(int j=0; j<3; j++)
  139.                 {
  140.                         board[i][j] = '_';
  141.                 }
  142.         }
  143.  
  144.         // DO YOU WANT TO GO FIST?
  145.         printf("Do you want to go first? (y/n): ");
  146.         // GET THE Y/N VALUE
  147.         char val;
  148.         scanf("%c", &val);
  149.         // ITS USERS TURN
  150.         if(val == 'y')
  151.                 Turn = true;
  152.         // ITS COMPUTERS TURN
  153.         else
  154.                 Turn = false;
  155.  
  156.         //  WHILE GAME IS GOING
  157.         while(Playing)
  158.         {
  159.                 // WHILE ITS USERS TURN
  160.                 if(Turn)
  161.                         UserMove();
  162.                 else
  163.                         ComputerMove();
  164.  
  165.                 // DRAW THE BOARD AT THE END OF EVERY TURN
  166.                 DrawBoard();
  167.         }
  168.  
  169.         // RETURN
  170.         return 0;
  171. }


Game_Ender Dec 19th, 2006 7:29 PM

The is the C++ forum, so while you can use the stdio.h function you can also use IO streams. Like "int val; cin >> val" is the same as "scanf("%d",&val"). That's not really important the more important thing is that where you get input from the user you don't check to make sure it was valid. This involves checking the return value of scanf, it is actually important. If scanf were to fail, you program would act randomly because you also don't provide default values for any variable user input is supposed to fill.

Disruptor Dec 19th, 2006 7:40 PM

I’m running Visual Studio C++ 2005 Express and when I clicked file->new project console application that include is what I got, I could try it with iostream instead but I’m unfamiliar with the way “<<” works printf seems more common to the way I code. But other than that the error checking would seem like a big problem. Error checking was never one of my main goals but that’s only because my teachers were lazy and didn’t assume anyone would put anything in besides the required values. I’ll go back through my code and add error checking. Also I was thinking about strategies for tic-tac-toe and will probably change the void computer move to treat any move value equal to or less than one as moving in corner positions that way its harder for the user if they go second.

DaWei Dec 19th, 2006 7:42 PM

You can find at least 3 implementations of Tic Tac Toe by searching the forum. They aren't all in the same language, but you should be able to pick up generalized approaches.

Like GameEnder, I would suggest that if you are going to use C++, you use C++ library functions. You will often find them to be more effective or powerful than the C equivalents (or near equivalents). Always read the documentation for the functions you use THOUROUGHLY. The high-dollar geeks who wrote the functions put those return values and error-checking functions there for a reason. If you skip error checking at this point, the price you pay will probably only be having your app run off into the weeds and puke on its shoes, or melt into a slag heap while eating your dog and homework. Please advance past the schlock, however, before you take on any medical equipment or space-shuttle stuff.

Disruptor Dec 19th, 2006 7:56 PM

Okay, I was unaware of which includes where c++ or c and I should make it practice to not let the overhead application add code that I have no idea what it does or where it came from. I suppose now would be a good time to add that I never really was taught in c++ not because I never chose to take a class on it just because my college never offered a class in it but that’s beside the point. Anyways, I’ve learned Java and Visual Basics so I know some fundamentals of Object Oriented Programming.

The problem I’m having is as follows. When I changed my include to: #include <iostream> it spit out an error saying that it was looking for stdafx.h? The exact error is as follows:

fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?

DaWei Dec 19th, 2006 8:09 PM

I suggest you turn off precompiled headers (look through the compiler options) and dump stdafx. It is nothing, at this point, as you'll see if you read it. With precompiled header off, it won't be automatically generated and placed in the project, next time. I usually find it's best to open the project as an empty project, also. I'm not a huge fan of auto-generated stuff, though it can sometimes ease the process for a novice.

Disruptor Dec 19th, 2006 8:18 PM

Okay done, I found precompiled headers in the ".vcproj" file when I opened it with notepad it was set to two and I simply changed that to zero and bam works. Duly noted I will now build projects as empty and add my own source and header files. My include file now works although it is having a problem with cout and cin? Not sure why errors are as follows:

error C2065: 'cout' : undeclared identifier
error C2065: 'cin' : undeclared identifier

This is what those errors are probably pointing to:

cout >> "\nHow many places over (0-2): ";
cin >> posX;

DaWei Dec 19th, 2006 10:52 PM

In C++ the things that are included in, for instance, iostream, belong to a namespace called std:. This allows you to distinguish between the standard library's cin and a function or name that you might invent called "cin". You resolve this by specifying which "cin" you mean. You may qualify it by means of a scope resolution operator, such as "std::cin". This would be a different thing than "myNamespace::cin". The quickest way to resolve this is to put, at the top of your file, "using namespace std;". This is not a good solution, since it tosses all symbols in the std namespace into your area. If you happen to use a symbol in the std namespace by accident (and there are tons of them), you are in deep doo doo. You can pick and choose by using such things as "using std::cin". Then you can reference cin without the scope resolution. Just don't make your own label or function named "cin" unless you remember to qualify IT, by saying something like "myNamespace::cin".

Disruptor Dec 22nd, 2006 2:31 AM

Okay so changing my code to reference every single cin and cout? Instead of “using namespace std;” Would that be more efficient or just more explicit in declaring what I want? Also would I type “using std::cin” or just “std::cin” because I figured out that std:: gives me a huge list of commands from the namespace std.

Bench Dec 22nd, 2006 10:00 AM

The difference between the 3 styles is the difference between whether or not you fill up your program's namespace scope with identifiers from the standard library.

The main idea of namespaces is to eliminate name clashes - so good practice is to make sure that identifiers remain confined to their own namespace, and aren't potentially clashing with other parts of the program

for this reason, its best to explicitly qualify every identifier from the standard library by prefixing it std:: - and avoid the using keyword entirely.


All times are GMT -5. The time now is 1:28 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC