I hope the complete lack of indentation and spacing errors in the output are simply due to the way you copied and pasted your code...
If you have an array of 8 elements, there is no element 8.
1 2
|
int fooey[8];
fooey[8] = 12; // <-- ERROR
|
Unfortunately, a lot of C++ compilers don't do bounds-checking at compile-time, but you can tell them to insert bounds-checking code when compiling. For example:
g++ -Wall -pedantic -fbounds-check Connect4.cpp -o Connect4
Then, when you run your program and it tries to access
board[8] your program will crash telling you that you've tried to access an invalid element, and you can fix it.
A related problem is that you keep assuming the size of the board throughout the program. Instead, use
consts to define the size of your array, and refer to them when you want to loop through its elements.
Your next problem is that you kept mixing up the row and column indices into your gameboard array. For example, in
checkForWin() your comment says "test horizontal victory" but you are actually checking for vertical victories.
The idea to have an extra array of
ints specifying the current height of a row is very interesting. Unfortunately it seems to have caused you the most grief. A better way is to just check to see whether the topmost row of the column has a piece in it or not.
Lastly,
system("PAUSE") is
evil. Please avoid it.
I hope you don't mind, but I've taken the liberty of modifying your code to implement some improvements and fix your bounds error:
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
|
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <limits>
using namespace std;
// standard Connect Four board size
const int NROWS = 6;
const int NCOLS = 7;
//globalvariable declarations
int board [NROWS][NCOLS] = {0, 0}; // make everything equal 0
// NOTE: The 8th row is the row that contains the height of the column
// I see what you are trying to do above.
// A better way is just to check to see if their is a piece in the
// topmost row of the column.
// Since the 8th row is messing you up, I've removed it.
int playerMove = 1; // which player's move it is.
int victory; // who has won (0 if no one)
// prototype declarations
void displayBoard ();
int inputNewMove ();
int checkForWin ();
void gameOver ();
//----------------------------------------------------------------------------
void pause()
{
// Please don't use system("PAUSE")
cin.seekg( 0, ios::end );
cin.clear();
cout << "Press ENTER to continue..." << flush;
cin.ignore( numeric_limits<streamsize>::max(), '\n' );
}
//----------------------------------------------------------------------------
int main ()
{
displayBoard ();
for (int i = 0 ; i < 15 ; i++)
{
cout << "Player " << playerMove << "'s turn." << endl;
// cout << board[8][1] << endl; I presume this is debug info
// cout << board[7][1] << endl; as the user won't care to see it.
// (besides which, I killed board[7]...)
inputNewMove ();
displayBoard ();
victory = checkForWin ();
if (victory > 0)
{
gameOver ();
return 0;
}
}
pause();
return 0;
}
//----------------------------------------------------------------------------
void displayBoard ()
{
// suggestion: use a lookup table
const char LUT[] = " 12";
cout << " 1 2 3 4 5 6 7 8" << endl;
cout << " ---------------";
for (int boardRow = 0 ; boardRow<NROWS ; boardRow++)// cycle through rows
{
cout << endl; // go to the next line
cout << (boardRow + 1) << "|";
for (int boardColumn = 0 ; boardColumn<NCOLS ; boardColumn++) // cycle through columns
{
cout << LUT[ board[boardRow][boardColumn] ] << ' ';
/*
if (board [boardRow][boardColumn] == 0) // empty
{
cout << " ";
}
if (board [boardRow][boardColumn] == 1) // player 1's piece
{
cout << "1 ";
}
if (board [boardRow][boardColumn] == 2) // player 2's piece
{
cout << "2 ";
}
*/
}
}
cout << endl << endl;
return;
}
//----------------------------------------------------------------------------
bool isColumnFull( int col )
{
return board[0][col] != 0;
}
//----------------------------------------------------------------------------
int inputNewMove()
{
int x;
int height;
for (;;)
{
cout << "Column? ";
cin >> x;
if ((x <= 8) && (x >= 1) && !isColumnFull( x-1 ))
{ //(board[8][x-1] != 8))
break;
}
else
{
cout << "Choice must be between 1 and 8, and column cannot be full." << endl;
}
}
// brilliant! however, since board[7] no longer exists...
// board[8][x-1]++; // adds one to the HEIGHT OF THE COLUMN VALUE (ROW 8)
// height = (8 - (board[8][x-1])); // determines point in array to fall (simulates the falling piece until it stops)
// search for the next available space
for (height=NROWS-1; board[height][x-1] != 0; height--);
board [height][x-1] = playerMove; // sets array coordinate to the number of the player
//switch move
if (playerMove == 1)
playerMove++;
else
playerMove--;
return 0;
}
//----------------------------------------------------------------------------
int checkForWin ()
{
//test for VERTICAL victory
for (int i=0; i<NCOLS-3; i++) // columns
{
for (int j=0; j<NROWS; j++) // rows
{
if (board[j][i] == 1 && board[j][i+1] == 1 && board[j][i+2] == 1 && board[j][i+3] == 1)
{
return 1;
}
if (board[j][i] == 2 && board[j][i+1] == 2 && board[j][i+2] == 2 && board[j][i+3] == 2)
{
return 2;
}
}
}
//test HORIZONTAL victory
for (int i=0; i<NCOLS; i++) // columns
{
for (int j=0; j<NROWS-3; j++) // rows
{
if (board[j][i] == 1 && board[j+1][i] == 1 && board[j+1][i] == 1 && board[j+1][i] == 1)
{
return 1;
}
if (board[j][i] == 2 && board[j+1][i] == 2 && board[j+2][i] == 2 && board[j+3][i] == 2)
{
return 2;
}
}
}
// don't forget to test for diagonal victory
// (combine what was done for your vertical and horizontal tests)
return 0;
}
//----------------------------------------------------------------------------
void gameOver()
{
cout << endl << "Game Over! Player " << victory << "has won!\n" ;
pause();
}
|
Hope this helps.
[edit] Oh yeah. You've done a very good job for just learning it. Very impressive!