Tic Tac Toe Program

Pages: 12
pleaseeee tell me ur opinon and ur suggestions
I borrowed from jason's code to my code like : board[3][3] , Thanks Jason :)
NEW CODE :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
#include <iostream>
#include <cstdlib>
#include <conio.h>
#include <string>
#include <ctime>
using namespace std;
//Winning info
struct win
{
    int Mini; // That equals 10 * row value + column value
    int Maxi;
    int a;
};

string board[3][3];
int turns;
win victory[2][8];
bool check(int a , int b)
{
    if ( board[a][b]!= " "  )
        return false;
    return true;
}

void counter(int x , int a , int b)
{
    if (  a==0 && b==0  )
    {
        victory[x][0].a ++;
        victory[x][6].a ++;
        victory[x][3].a ++;
    }

    if (  a==0 && b==1 )
    {

        victory[x][0].Mini += 1;
        victory[x][4].Mini += 1;
        victory[x][0].a ++;
        victory[x][4].a ++;
    }

    if (  a==0 && b==2  )
    {
        victory[x][0].Mini += 2;
        victory[x][5].Mini += 2;
        victory[x][7].Mini += 2;
        victory[x][0].a ++;
        victory[x][5].a ++;
        victory[x][7].a ++;
    }

    if (  a==1 && b==0 )
    {
        victory[x][3].Mini += 10;
        victory[x][1].Mini += 10;
        victory[x][1].a ++;
        victory[x][3].a ++;
    }

    if (  a==1 && b==1 )
    {

        victory[x][6].Mini += 11;
        victory[x][7].Mini += 11;
        victory[x][4].Mini += 11;
        victory[x][1].Mini += 11;
        victory[x][6].a ++;
        victory[x][7].a ++;
        victory[x][4].a ++;
        victory[x][1].a ++;
    }

    if (  a==1 && b==2  )
    {

        victory[x][5].Mini += 12;
        victory[x][1].Mini += 12;
        victory[x][1].a ++;
        victory[x][5].a ++;
    }

    if (  a==2 && b==0 )
    {

        victory[x][7].Mini += 20;
        victory[x][2].Mini += 20;
        victory[x][3].Mini += 20;
        victory[x][7].a ++;
        victory[x][2].a ++;
        victory[x][3].a ++;
    }

    if (  a==2 && b==1 )
    {

        victory[x][2].Mini += 21;
        victory[x][4].Mini += 21;
        victory[x][2].a ++;
        victory[x][4].a ++;
    }

    if (  a==2 && b==2 )
    {

        victory[x][6].Mini += 22;
        victory[x][2].Mini += 22;
        victory[x][5].Mini += 22;
        victory[x][6].a ++;
        victory[x][2].a ++;
        victory[x][5].a ++;
    }
}
void computer()
{
    bool l;
    int f;
    int a = 0 ,  b = 0 ;

    if ( false )
    {
        hi :
        counter (1 , a , b);
        board[a][b] = "O" ;
        return ;

    }
    // Attack , Defence
    for(int i = 1 ; i>=0 ; i--)

        for(int j=0 ; j<=7 ; j++)

            if( victory[i][j].a == 2 )

                if ( check( (( victory[i][j].Maxi - victory[i][j].Mini ) / 10 ) , ( ( victory[i][j].Maxi - victory[i][j].Mini ) % 10 )  ) == true )
                {
                    a = (( victory[i][j].Maxi - victory[i][j].Mini ) /10 )  ;
                    b = (( victory[i][j].Maxi - victory[i][j].Mini ) %10 )  ;
                    goto hi;
                }

    if ( check (0,0) == true || check(1,1) == true || check(2,2) == true || check(2,0) == true || check(0,2) == true )
        l=true;

    // Play strategy :D

    while ( true )
    {
        f = rand() % 4 + 1;
        if ( f == 1 )
        {
            while(true)
            {
                a = rand() % 3 ;
                b = rand() % 3 ;
                if(check (a,b)==true)
                    goto hi;

            }
        }
        else if ( l == true )
        {
            while (true)
            {
                f = rand() % 5  ;
                if( f<=2 )
                {
                    b = a = f;
                    if(check (a,b)==true)
                        goto hi;
                }
                else if ( f == 3)
                {
                    a=0;
                    b=2;
                    if(check (a,b)==true)
                        goto hi;
                }
                else if ( f == 4 )
                {
                    a=2;
                    b=0;
                    if(check (a,b)==true)
                        goto hi;
                }
            }
        }
    }

}
void cleaner()
{
    for (int i = 0; i <= 1; i++)
    {

        for (int j = 0; j <= 7; j++)
        {
            victory[i][j].Mini = 0;
            victory[i][j].a    = 0;
        }
    }
    turns = 1;
    for(int i=0; i<=2; i++)
        for(int j=0; j<=2; j++)
            board[i][j]=" ";
}

void Table()
{
    system("cls");
    cout<<endl<<"This Game was designed by AHMED ESSAM :) "<<endl<<endl;

    for (int rows = 1; rows <= 13; rows++)
    {

        if( (rows-1)  %4==0)
            cout<<string(25,'-')<<"       " <<string(25,'-');
        else
        {
            for(int j=0; j<=3; j++)
            {
                if( (rows==3 || rows==7 || rows==11) && j!=3 )
                    cout<<"|   "<< board [ (rows+1) /4 -1 ] [j]<<"   ";
                else
                    cout<<"|       ";
            }
            for(int j=0; j<=3; j++)
            {
                if( (rows==3 || rows==7 || rows==11) && j!=3 )
                    cout<<"|   "<< ((rows+1) /4)*3 - 2 +j  <<"   ";
                else
                    cout<<"|       ";
            }
        }

        cout<<endl;
    }
}

void InputCheck(int ys , int wf)
{
    int a , b ;
    if ( ys == 1 || wf == 0  )
    {
        string tempp="";
        while(true)
        {
            cout<<endl<<"Where would you like to play :) ? "<<endl<<endl;

            while (true)
            {
                cin>>tempp;
                if(tempp != "1" && tempp != "2" && tempp !="3" && tempp != "4" && tempp != "5" && tempp != "6" && tempp != "7" && tempp != "8" && tempp != "9")
                    cout<<"              ERROR"<<endl;
                else
                    break;
            }

            int temp;
            temp = atoi(&tempp[0]);
            if( temp <= 3  )
            {
                a=0;
                b=temp-1;
            }
            else if ( temp >= 4 && temp <= 6  )
            {
                a = 1 ;
                b = temp - 4 ;
            }
            else if ( temp >= 7 && temp <= 9 )
            {
                a = 2 ;
                b = temp - 7 ;
            }
            if (check(a,b) == true )
            {
                if ( wf == 0 )
                {
                    board[a] [b]="X";
                }
                else
                board[a][b]="O";
                counter(wf , a,b )  ;
                return;

            }
            else
                cout<<"Already Entered";
        }
    }
    computer();
    return;
}
void WhoWins()
{
    while(false)
    {
hey :
        getch();
        cleaner();
        Table();
        return;
    }
    //Player 1
    for (int i  =0; i <= 7; i++)
    {

        if(victory[0][i].a==3)
        {
            cout<<"Player 1 WON ";
            goto hey ;
        }
    }
    //Player 2
    for (int i = 0; i <= 7; i++)
    {

        if(victory[1][i].a==3)
        {
            cout<<"Player 2 WON " ;
            goto hey ;
        }
    }

    //Noone won
    if ( turns == 10 )
    {
        cout<<"Nobody WON !! " ;
        goto hey ;
    }

}

int main()
{
    srand( time( NULL ) );
    string temp;
    int yc; //Your Choice
    int wf; // Who First

    cout<<"               Choose : "<<endl<<"      1 - Play against friend "<<endl<<"      2 - Play against Computer " <<endl<<endl<<"      " ;

o:

    cin >> temp;
    if (temp != "1" && temp != "2" )
    {

        cout<<"          ERROR "<<endl<<"      ";
        goto o;
    }
    yc=atoi(&temp[0]);

    cout<<endl<<"      1 - Player 1 first 'X' "<<endl<<"      2 - Player 2 first (or computer) 'O'"<<endl<<endl<<"      ";
oo:
    cin >> temp;
    if (temp != "1" && temp != "2" )
    {

        cout<<"          ERROR "<<endl<<"      ";
        goto oo;
    }
    wf=atoi(&temp[0]) - 1;
    for (int i = 0; i <= 7; i++)
    {
        victory[i][0].Maxi = 3;
        victory[i][1].Maxi = 33;
        victory[i][2].Maxi = 63;
        victory[i][3].Maxi = 30;
        victory[i][4].Maxi = 33;
        victory[i][5].Maxi = 36;
        victory[i][6].Maxi = 33;
        victory[i][7].Maxi = 33;
    }
    cleaner();
    for (turns = 1 ;; turns ++)
    {
        Table();
        WhoWins();
        InputCheck(yc , wf);
        wf=1-wf;
    }
    // end of 'o:'
}
Last edited on
Having spaghetti code is the problem :)
It is a good practice to avoid using gotos as much as possible to avoid disjointed code.

Did you try to even compile the code?


1
2
main()
{

you need int main()

win win[2][9]
you can't have a variable name the same as the data type'

change all of your 'and's and 'or's to && and ||


and ect.


Last edited on
okay will do now :D sry still beginner
about main()
yea my compile can compile it with no bugs
new code ... i hope it compiles with no errors :D
Last edited on
your game plays ok.

but you most remember that readability is of utmost importance.
You format is consistent, but with the lack of white space it's very hard for somebody recognize your logic and suggest changes.

I have reformatted you code:

Last edited on
Thanks for advice Jason and i hope i use ur advice well and thanks for reformatting my code :) i replaced mine code with yours :D
Last edited on
I found a little bug ,if you enter a non-integral number the program prints Enter (...) ERROR infinitely and you should also have some way to exit the program
Last edited on
yea i know , and if you entered a string that would happen too , cuz the variables are integers so you can't enter decimal or string , actually i can't resolve this problem cuz if i changed int to float still you can enter string and the same would happen .
When I made tic-tac-toe in the console I avoided that problem by making them input to a char variable then checking if it was valid, and if so assign the proper values to two integers. I.e if the char was '1' the integer would then be 1 because it would check what the char was.

1
2
3
4
5
void Player::convert_toCoords(){
	if(Player::getPlayer_charInput() == '1'){
		Player::x_coord = 1;
	}
}
Last edited on
Well , nice idea :D iam going to make it soon i will post the new code
btw try the game and criticize it please :D
and WHY I CAN'T POST THE CODE Q_Q
always get ERROR:CONTENT LONG
Last edited on
Well , done no such buggs again , i used atoi() function
here is the code
http://txtup.co/vKMPy
Last edited on
this part is really funny: line 74-82

1
2
3
4
5
6
7
8
9
10
lol:
				srand( time( NULL ) );
				info[turns].rv = rand() % 10;

				if (info[turns].rv == 0)
					goto lol;

				if (info[turns].rv > 3)
					info[turns].rv=info[turns].rv/3;

if you want a random number between 1 and 3 all you need to do is
(rand() % 3) + 1;

this gives you theoretically 33 percent chance to get either one of them, notice that what your doing your more likely to get 1 or 2 then three.
youll get 2 if the rand()%10 returns you 2,6,7,8 but youll get 3 only if it returns 3,9, (this is caused because of the flooring when dividing ints). funny stuff. also you dont need to seed all the time, you only need to do it once! this is a constantly accessible function and you are seeding way to many times, so basically you only need to seed once in the beginning of main and that should be enough.
Last edited on
another tip,

all your functions share the
return foo(infos *info , int turns)

then why not make int array of infos and turns global? you did it with the two dimensional array of victories, then why not these?
Thanks for tips bro :) if you find any more stupid things please mention it

Last edited on
LordAhmed, you've inspired me to create my own tic tac toe game. :)

Last edited on
we should all make tic tac toes and have them play against each other lol

btw lord ahmad, if you want to really really improve your code.

consider changing the way you store the board.
i mean, instead of having an array of 10 infos, maybe have a two dimensional array of chars representing the board?

char board[3][3];

where board[x][y] can be either 'X','O',or ' '.

anyways your way good too just not for this particular task, since you dont really need to know the past history of moves, so you dont really need to save who did what moves, theoretically you only need the current position on the board and whos turn it is. And that should be what the computer AI is based on.

I also noticed your PutInOrder(...) function, the games seems to work without this function in the main loop but it has a bug. Try fixing the bug without having to sort the entire history of moves all the time,( you probably just forgot to update the members of info somewhere ). Because you see, programming is like medicine, you want to treat the source of the problem and not the symptom. If you write code2 to fix bugs of code then you might need code3 to fix the bugs of code2 and then you'll just need code4 to fix the bugs in code3 and so on, so its always better to just fix the bugs without adding new code segments.
Last edited on
Jason , there is a bug in your game
try to play against cpu and put '5' then '1' and u will see
char board[3][3] !! Wonderful idea :D I used it in my new code
thanks Tiny I have done what you said and I fixed PutInOrder bug there is no more this function

Last edited on
.....
Last edited on
Just a very small thing:

jasonXcoder wrote:
change all of your 'and's and 'or's to && and ||


and & or are valid C++11 code- although everyone is much more used to && and ||
NEW CODE PLEASEEEEE TELL ME UR OPINION
(Its up in the topic :D)

You are right TheIdeasMan :D
Last edited on
ok, the new code looks great, and very appealing to play too. good job.

some improvements to your code without actually changing anything in the design.

1: line 300 - //Table(); is not necassary. you do Table later anyway.

2: line 174 -
1
2
                    a=f;
                    b=a;
you could just do b = a = f; I love concatenating assignment.

3: function counter(), line 26 -
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void counter(int wf , int a , int b)
{
    int x=wf;


    if (  a==1 && b==1  )
    {
        victory[x][1].Mini += 11;
        victory[x][1].a ++;
        victory[x][7].a ++;
        victory[x][4].a ++;
        victory[x][7].Mini += 11;
        victory[x][4].Mini += 11;
    }


its unnecassary to turn wf into x, you could just pass wf inside, or called the argument in the function x. like this.

1
2
3
4
5
6
7
8
9
10
11
12
void counter(int x , int a , int b)
{

    if (  a==1 && b==1  )
    {
        victory[x][1].Mini += 11;
        victory[x][1].a ++;
        victory[x][7].a ++;
        victory[x][4].a ++;
        victory[x][7].Mini += 11;
        victory[x][4].Mini += 11;
    }


the argument name in the function defenition dont have to match the argument name in the function call.

4: line 153 - the outer while(true) is unnecessary
5: line 167 - the check if l!=1 is unnecessary
6: true programmers start counting at zero!

1
2
3
string board[4][4];
int turns;
win victory[3][9];


all your arrays are one size bigger then what they are supposed to be, on the possitive side you can start counting like a human being from 1, but then again we are not humans, we be programmers++.
Pages: 12