Help! Debugging. Input glitched!

Hello,

Below is a program I wrote that is supposed to play the game Connect 4. I feel like its practically done, but I keep running into this weird bug randomly when playing it- and it causes me to not be able to finish a game.

After taking a few inputs, the program will suddenly drop, and it wont do anything other than let you input what you want in futility.

I feel like this might be an easy fix, and something that I'm just unaware of as a noobie.


The program seems to always have its hiccup on the test_gamestate function. So you may only need to look at line 126 and down.
EDIT: It seems this program is more busted than I am aware of- When I column is totally filled, I get a segmentation fault. And the game doesnt know when someone won. *sigh*

IMPORTANT NOTE ON RUNNING THIS PROGRAM:
It takes command line arguments to function properly.

please launch the program in the following format:
./a.out 2 [number of rows] [number of columns]
Ex:
./a.out 2 4 10

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
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <string>

using namespace std;


//Validate Input
int getnumber(int cols){

   int n;
   cin >> n;
   while(cin.fail() || n < 0 || n >= cols)
   {
     cin.clear();
     cin.ignore();
     cout << "Please enter a valid column: ";
     cin >> n;
   }
   return n;
}





//Dropping the Token
void drop_token(char** board_ar, int rows, int cols, char player, int choice, int* position){
	bool placed = false;

	for(int i=0; i<rows;i++){
	   if(board_ar[i][choice] == 'Y' || board_ar[i][choice] == 'R'){  // Token gets placed ontop of another token
	      board_ar[i-1][choice] = player;
	      placed = true;
	      position[0] = i - 1;
	      position[1] = choice;
	      break;
	   }

	}
        if(placed == false){                                              // Token gets placed at the bottom of a column
	board_ar[rows - 1][choice] = player;    
	position[0] = rows - 1;
	position[1] = choice;
	}	

}



//Choosing a Column
int select_col(char** board_ar, int rows, int cols, char player){

   int choice = 0;   
   
 
   do{

   cout << "Player " << player << ", choose an appropriate column to drop your token in." << endl;
   choice = getnumber(cols);

   }while(board_ar[0][choice] == 'R' || board_ar[0][choice] == 'Y');
  
   return choice;	
  }




//Display Current Board
void display_board(char** board_ar,int rows,int cols){

   cout << "--------Columns--------" << endl;
   for(int i=0; i<cols;i++){
   cout << i;
   }
   cout << endl;
   for(int j=0;j<cols;j++){
      cout << "*";
   }
   cout << endl;
 
   for(int i=0; i<rows;i++){
      for(int j=0;j<cols;j++){
	 cout << board_ar[i][j];
      }
      cout << endl;
   } 
   cout << "\n\n\n" << endl;                // leave extra space on bottom
}


//Check Game State
int check_gamestate(char** board_ar, int rows, int cols, char player, int* position){

   //Checking the Gamestate: Seperate Counts for each:
   //1) Function that checks vertical match
   //2) Function that checks left and right match
   //3) Function that checks up left and down right
   //4) Function that cheks up right and down left


  int vert_token_count=0;
  if(position[0] + 3 < rows){
     cout << "Entered vert count" << endl;
     for(int j = 1;j<rows;j++){
       board_ar[position[0]+j][position[1]];
       if(board_ar[position[0]+j][position[1]] == player && position[0]+j < rows){
          cout << "Ping" << endl;
       }
     } 
  }
  //cout << "vertical token count = " << vert_token_count << endl;
  return 0;
}



//TEST FUNCTION:
//



int test_gamestate(char** board_ar, int rows, int cols, char player, int* position){

   int vertical = 1;
   int horizontal = 1;
   int diagonal1 = 1;//(\)
   int diagonal2 = 1;//(/)
   int i; //vert
   int ii; //horiz
   //Check vertical
   for(i = position[0] +1; board_ar[i][position[1]] == player && i < rows;i++,vertical++);  //down            *** May need to adjust rows
   for(i = position[0] -1; board_ar[i][position[1]] == player && i >= 0;i--,vertical++);   // up
   if(vertical >= 4)return 1;
   //Check Horizontal 
   for(ii = position[1] -1; board_ar[position[0]][ii] == player && ii >= 0;ii--, horizontal++) //left
   for(ii = position[1] +1; board_ar[position[0]][ii] == player && ii < cols;ii++, horizontal++) //right       *** May need to adjust cols
   if(horizontal >= 4)return 1;
   //Check Diagonal 1 (\)
   for(i = position[0] -1, ii = position[1] -1; board_ar[i][ii] == player && i >=0 && ii >=0; diagonal1++, i--, ii--); // up and left
   for(i = position[0] +1, ii = position[1] +1; board_ar[i][ii] == player && i < rows && ii < cols; diagonal1++,i++,ii++); // down and right
   if(diagonal1 >= 4)return 1;
   //Check Diagonal 2 (/)
   for(i = position[0] -1, ii = position[1] +1; board_ar[i][ii] == player && i >= 0 && ii < cols; diagonal2++, i--, ii++); // up and right
   for(i = position[0] +1, ii = position[1] -1; board_ar[i][ii] == player && i < rows && ii >= 0; diagonal2++, i++, ii--); // down and left
   if(diagonal2 >= 4)return 1;

   return 0;




}






/********************************
 COMMAND LINE ARGUMENTS MUST BE 
 ENTERED IN THE FOLLOWING ORDER:
 [NUMBER OF PLAYERS] [ROWS] [COLUMNS]
 *******************************/
int main(int argc, char* argv[]){
   int game_state = 0;                 // variable to check state of the game
   int choice = 0;                     // Selected column number
   int num_players = atoi(argv[1]);    // Number of players
   int rows = atoi(argv[2]);           // rows cmd line input
   int cols = atoi(argv[3]);           // columns cmd line input
   char player;                        // Current player
   int* position = new int[2];	       // Where token is placed (used to check game state)
   for(int i=0;i<2;i++)
      position[i] = 0;

   char** board_ar = new char*[rows];  // Connect 4 grid creation
   board_ar[0] = new char[rows*cols];
  
  for(int i =0;i<cols;i++){
      board_ar[i] = board_ar[0] + i*cols;                    //initialize board_ar with rows
   }

   for(int i=0; i<rows;i++){
      for(int j=0;j<cols;j++){
	 board_ar[i][j] = '0';                               // populate board_ar with initial chars
      }     
   }
   do{
   player = 'R';                                             // Player One Turn
   display_board(board_ar, rows, cols);

   choice = select_col(board_ar, rows, cols, player);
   
   drop_token(board_ar, rows, cols, player, choice, position);

   display_board(board_ar, rows, cols);

     //game_state = check_gamestate(board_ar, rows, cols, player, position);

   game_state = test_gamestate(board_ar, rows, cols, player, position);

      if(game_state == 0){
	 player = 'Y';

	 if(atoi(argv[1]) == 1){/*Ai_turn*/}
	 
	     
	 if(atoi(argv[1]) == 2){   // Player Two Turn
		   
	 display_board(board_ar, rows, cols);
 
      	 choice = select_col(board_ar, rows, cols, player);

	 drop_token(board_ar, rows, cols, player, choice, position);

      	 display_board(board_ar, rows, cols);

      	// game_state = check_gamestate(board_ar, rows, cols, player, position);
	 game_state = test_gamestate(board_ar, rows, cols, player, position);
	 }

      
      }
   }while(game_state == 0);
   if(game_state == 1){
   cout << "YOU WIN! WE DID IT!!!!" << endl;}
  // delete[][] board_ar;
return 0;
}







Thank you so much for looking at this.
I'm very grateful as it is due in just a few hours. ! :/

P.S. I know that I'm not using the 'check_gamestate' function.
Last edited on
1. Learn how to use a debugger.
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
 g++ -g main.cpp
$ gdb -q ./a.out
Reading symbols from ./a.out...done.
(gdb) run 2 4 10
Starting program: /home/sc/Documents/a.out 2 4 10
/// snipped
Player Y, choose an appropriate column to drop your token in.
4

0123456789
**********
0000000000
0000000000
00RYY00000
00RYR00000




5

5
^C
Program received signal SIGINT, Interrupt.
0x00000000004011bc in test_gamestate (board_ar=0x614c40, rows=4, cols=10, player=89 'Y', position=0x614c20) at main.cpp:139
139	   for(ii = position[1] -1; board_ar[position[0]][ii] == player && ii >= 0;ii--, horizontal++) //left
(gdb) bt
#0  0x00000000004011bc in test_gamestate (board_ar=0x614c40, rows=4, cols=10, player=89 'Y', position=0x614c20) at main.cpp:139
#1  0x0000000000401614 in main (argc=4, argv=0x7fffffffdf28) at main.cpp:222
(gdb) list
134	   //Check vertical
135	   for(i = position[0] +1; board_ar[i][position[1]] == player && i < rows;i++,vertical++);  //down            *** May need to adjust rows
136	   for(i = position[0] -1; board_ar[i][position[1]] == player && i >= 0;i--,vertical++);   // up
137	   if(vertical >= 4)return 1;
138	   //Check Horizontal
139	   for(ii = position[1] -1; board_ar[position[0]][ii] == player && ii >= 0;ii--, horizontal++) //left
140	   for(ii = position[1] +1; board_ar[position[0]][ii] == player && ii < cols;ii++, horizontal++) //right       *** May need to adjust cols
141	   if(horizontal >= 4)return 1;
142	   //Check Diagonal 1 (\)
143	   for(i = position[0] -1, ii = position[1] -1; board_ar[i][ii] == player && i >=0 && ii >=0; diagonal1++, i--, ii--); // up and left
(gdb) print horizontal 
$1 = -1829364223

So I pressed ctrl-c (that's the SIGINT) because the program had halted internally, and not processing any more input.
Notice the WTF value for horizontal.


2. Learn how to indent code properly.
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
int test_gamestate(char **board_ar, int rows, int cols, char player,
                   int *position)
{
  int vertical = 1;
  int horizontal = 1;
  int diagonal1 = 1;            //(\)
  int diagonal2 = 1;            //(/)
  int i;                        //vert
  int ii;                       //horiz
  //Check vertical
  for (i = position[0] + 1; board_ar[i][position[1]] == player && i < rows; i++, vertical++); //down            *** May need to adjust rows
  for (i = position[0] - 1; board_ar[i][position[1]] == player && i >= 0; i--, vertical++); // up
  if (vertical >= 4)
    return 1;
  //Check Horizontal
  for (ii = position[1] - 1; board_ar[position[0]][ii] == player && ii >= 0; ii--, horizontal++)  //left
    for (ii = position[1] + 1; board_ar[position[0]][ii] == player && ii < cols; ii++, horizontal++)  //right       *** May need to adjust cols
      if (horizontal >= 4)
        return 1;
  //Check Diagonal 1 (\)
  for (i = position[0] - 1, ii = position[1] - 1; board_ar[i][ii] == player && i >= 0 && ii >= 0; diagonal1++, i--, ii--);  // up and left
  for (i = position[0] + 1, ii = position[1] + 1; board_ar[i][ii] == player && i < rows && ii < cols; diagonal1++, i++, ii++);  // down and right
  if (diagonal1 >= 4)
    return 1;
  //Check Diagonal 2 (/)
  for (i = position[0] - 1, ii = position[1] + 1; board_ar[i][ii] == player && i >= 0 && ii < cols; diagonal2++, i--, ii++);  // up and right
  for (i = position[0] + 1, ii = position[1] - 1; board_ar[i][ii] == player && i < rows && ii >= 0; diagonal2++, i++, ii--);  // down and left
  if (diagonal2 >= 4)
    return 1;

  return 0;
}

Do you now see the oddness of your Horizontal checks compared to the others.
Just one missing ; and the character of the loops is completely changed.

FWIW, always write your empty statements like so, to make your intentions obvious.
1
2
3
for ( blah ) {
    ; // empty
}

Last edited on
Thank you for your guidance.

1
2
3
4
5
6
7
8
9
10
11
12
13

         ,     ,
           |\."./|
          / _   _ \
         / {|} {|} \  _
         \==  Y  ==/ ( \
          ;-._^_.-;   ) )
         /   \_/   \ / /
         |   (_)   |/ /
        /|  |   |  |\/
       | |  |   |  | |
        \|  |___|  |/
         '""'   '""' 
Topic archived. No new replies allowed.