using System;
public class Proj6
{
public static string[,] board = new string[6, 7];
public static int[] columns = new int[7];
public static void Main()
{
bool game = true;
Proj6.columnCount();
while (game)
{
Proj6.move1();
Proj6.move2();
}
}
public static int Row(int n)
{
int m = n;
columns[m] -= 1;
return columns[m];
}
public static void columnCount()
{
for (int i = 0; i < columns.Length - 1; i++)
{
columns = 5;
}
}
public static void move1()
{
Proj6.printBoard();
Console.Write("\nUser 1 (O), enter a column (0-6): ");
int move = Convert.ToInt32(Console.ReadLine());
int row = Proj6.Row(move);
board[move, row] = "O";
}
public static void move2()
{
Proj6.printBoard();
Console.Write("\nUser 2 (X), enter a column (0-6): ");
int move = Convert.ToInt32(Console.ReadLine());
int row = Proj6.Row(move);
board[move, row] = "X";
}
public static void Board()
{
bool buildBoard = true;
while (buildBoard)
{
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 7; j++)
{
board[i, j] = "_ ";
}
}
buildBoard = false;
}
}
public static void printBoard()
{
{
Console.WriteLine("Current Board (user1 = O, user2 = X): \n");
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 7; j++)
{
Console.Write(board[i, j]);
if (j == 6)
{
Console.WriteLine();
}
}
}
}
}
}
C# Connect Four game help
Hi everyone, Im trying to write a program for a connect four game. This code doesnt print the _'s of my board and im not sure why. It also print my moves side ways when im wanting it to print upwards like a regular connect four game.
Thanks everyone for your help
It looks like your Board function (the one that initializes your board with '_') is never called.
As far as your moves, the problem lies in a couple of places. Carefully inspect your Row function. Keep in mind what you initialize the column array to, and what happens when a piece is placed in a column. Actually step through the code with a pencil and paper and see what happens. Compare that to what you expect to happen. It's a small mistake that you won't catch unless you actually follow your own code and see it yourself.
Also take a closer look at this line in your move functions.
Are you sure you're indexing board the right way? Did you intend for it to be indexed by [row, column] or by [column, row]. Hint: There are only two ways to index it and your program is misbehaving, so it must be the other way!
As far as your moves, the problem lies in a couple of places. Carefully inspect your Row function. Keep in mind what you initialize the column array to, and what happens when a piece is placed in a column. Actually step through the code with a pencil and paper and see what happens. Compare that to what you expect to happen. It's a small mistake that you won't catch unless you actually follow your own code and see it yourself.
Also take a closer look at this line in your move functions.
board[move, row] = "O";
Are you sure you're indexing board the right way? Did you intend for it to be indexed by [row, column] or by [column, row]. Hint: There are only two ways to index it and your program is misbehaving, so it must be the other way!
Quote:Original post by guzumba
This code doesnt print the _'s of my board and im not sure why.
You never actually call the Board() function.
Quote:It also print my moves side ways when im wanting it to print upwards like a regular connect four game.
Look carefully at the code that actually puts the moves into the grid. Which index represents rows and which represents columns? Should the user be specifying a row or a column? Therefore...
You're also doing a bunch of rather strange and/or useless things. Of note:
0)
public class Proj6{
Clearly you don't intend to make objects of type Proj6 (BTW, what on earth kind of name is that?) but are just using it to store static functions. This is C#, not Java. You have namespaces; use them.
1)
public static void Main() { bool game = true; Proj6.columnCount();
Repeated several times: You're already writing code within Proj6, so you don't need to say to look for a function within Proj6. That will be the first place the compiler looks.
2)
public static int Row(int n) { int m = n; columns[m] -= 1; return columns[m]; }
Why not just use n directly?
3)
public static void move1() public static void move2()
Can you think of a way to use the same function for both tasks? What are the differences between the two functions? In programming, we constantly seek to find things that are almost the same, and handle them in one spot: that way, if we change our mind about the handling, we only have to change it in one place.
4)
public static void Board() { bool buildBoard = true; while (buildBoard) { ... buildBoard = false; } }
Exactly what purpose do you think the outer while loop is serving?
Thanks for the post everyone! I have fixed alot of the code and gotten alot farther. To answer your question about why im using "public class Proj6". I havent really learned about namespaces yet. Im sure its coming up in the book im reading. Im also typing "Proj6.Board();" instead of "Board();" because im getting used to calling class names. I was reading that you do this for calling classes from other files.
Here is the code I have updated. I am still needing help though. Im needing help checking for a winner. Ive tried a couple things but nothing is coming to mind. Im thinking I have to check the board array with a for loop, and have if statements within. But im confused how to get started. If anyone can help me get started that would be awesome. Thanks everyone!
Here is the code I have updated. I am still needing help though. Im needing help checking for a winner. Ive tried a couple things but nothing is coming to mind. Im thinking I have to check the board array with a for loop, and have if statements within. But im confused how to get started. If anyone can help me get started that would be awesome. Thanks everyone!
using System;public class Proj6{ public static string[,] board = new string[6, 7]; public static int[] columns = new int[7]; public static bool playerX = true; public static bool game = true; public static void Main() { // controls the flow of the program by calling various methods // and has while loop for repeating certain method calls Proj6.columnCount(); Proj6.Board(); while (game) { Proj6.move(); Proj6.winner(); Proj6.boardFull(); } } public static int Row(int n) { // makes sure pieces are not replacing opponent // players pieces by returning spot for piece to fall columns[n] -= 1; return columns[n]; } public static void columnCount() { // tells program bottom of game board starts // and where the pieces must fall in each column for (int i = 0; i < columns.Length; i++) { columns = 6; } } public static void move() { // ask user for column number and places an X or O // on board at column number user selected Proj6.printBoard(); if (playerX) { Console.Write("\nUser 1 (X), enter a column (0-6): "); } else { Console.Write("\nUser 1 (O), enter a column (0-6): "); } int move = Convert.ToInt32(Console.ReadLine()); int row = Proj6.Row(move); if (playerX) { board[row, move] = "X "; playerX = false; } else { board[row, move] = "O "; playerX = true; } } public static void Board() { // builds board array, blank board with _'s for (int i = 0; i < 6; i++) { for (int j = 0; j < 7; j++) { board[i, j] = "_ "; } } } public static void printBoard() { // prints updated board _'s replaced with // X's and O's at users column choice Console.WriteLine("Current Board (user1 = X, user2 = O): \n"); for (int i = 0; i < 6; i++) { for (int j = 0; j < 7; j++) { Console.Write(board[i, j]); if (j == 6) { Console.WriteLine(); } } } } public static void boardFull() { // adds up X's and O's to see if board is full // and if a tie has occurred int total = 0; for (int i = 0; i < 6; i++) { for (int j = 0; j < 7; j++) { if (board[i, j] == "X " || board[i, j] == "O ") { total += 1; if (total == 42) { Proj6.printBoard(); Console.WriteLine("\nIts a tie..."); game = false; break; } } } } } public static void winner() { // checks if player 1 or 2 has connected four pieces // either horizontal, vertical or diagonal }}
Here's my implementation of your Connect4 game.
using System;// we use namespaces to help organize our projects and keep name// clashes from happening. This let's us use more descriptive// names for our types without fear of having them conflict// with a built-in type.namespace Connect4{ // instead of having two dimensional arrays, which are // unwieldy, let's divide some of the work into another class class Row { char[] pieces; public char[] Pieces { get { return pieces; } } public Row(int columnCount, char emptyCharacter) { pieces = new char[columnCount]; for (int i = 0; i < columnCount; i++) pieces = emptyCharacter; } } // give your classes descriptive names. There's no // need to abreviate anything; it really won't save // you any time. class Connect4Game { // these constants make changing the size of // the board easy. You only have to do it in one place const int RowCount = 6; const int ColumnCount = 7; // this is the entry point for the game static void Main() { // define the characters that will represent each piece char[] pieceCharacters = new char[3]; pieceCharacters[0] = '_'; pieceCharacters[1] = 'X'; pieceCharacters[2] = 'O'; // define the rows of the game board Row[] rows = new Row[RowCount]; for (int i = 0; i < RowCount; i++) rows = new Row(ColumnCount, pieceCharacters[0]); // this will hold the player who is going // to make his move next. we start with player 1, // and alternate between him and player 2 int currentPlayer = 1; int previousPlayer = 2; // enter the main loop. we should loop // until the user wants to exit while (true) { // clear the screen each time we loop Console.Clear(); // draw the board DrawBoard(rows); // check for a full board (tie) if (CheckForTie(rows, pieceCharacters[0])) { // the game's over, and the result is a tie. break out of the loop // to end the game Console.WriteLine("It's a tie!"); break; } else if (CheckForWin(rows, pieceCharacters[previousPlayer])) { // the game's over, and one of the players won. since one of the players // just made a move, he's the one that won the game Console.WriteLine("Player " + previousPlayer + " (" + pieceCharacters[previousPlayer] + ") wins!"); break; } // prompt the user for a move Console.Write("Player " + currentPlayer + " (" + pieceCharacters[currentPlayer] + "), "); Console.Write("enter a column (1 - 7): "); // read the input. if the user doesn't enter a valid answer, we will tell him so and // then loop around to let him try again string input = Console.ReadLine(); int choice = 0; if (!int.TryParse(input, out choice) || choice < 1 || choice > 7 || !AddPiece(rows, choice - 1, pieceCharacters[currentPlayer])) { // tell the user that he screwed up Console.WriteLine(); Console.WriteLine("Invalid input. Please try again."); Console.WriteLine("-- Press any key to continue --"); // wait for confirmation before continuing Console.ReadLine(); } else { // otherwise, update the current player and wait for another turn previousPlayer = currentPlayer; if (currentPlayer == 1) currentPlayer = 2; else currentPlayer = 1; } } // the game's done now Console.WriteLine("Thanks for playing!"); Console.WriteLine("-- Press any key to exit --"); Console.ReadLine(); } // this function will draw the board for us static void DrawBoard(Row[] rows) { // print each row foreach (Row row in rows) Console.WriteLine(row.Pieces); Console.WriteLine(); } // this function adds a piece to the board, figuring // out the correct row it should go in // if we can't add the piece (because the column is full), // we will return false to indicate an error static bool AddPiece(Row[] rows, int column, char character) { // work our way up from the bottom, with the last row // in the array being the bottom of the board for (int i = rows.Length - 1; i >= 0; i--) { // if this row is empty here, we can add the piece if (rows.Pieces[column] == '_') { // once we add the piece, we don't need to loop anymore rows.Pieces[column] = character; return true; } } // if we made it this far, the column is full // return false to indicate an error return false; } // this function checks for a full board, which indicates a tie static bool CheckForTie(Row[] rows, char emptyPiece) { // check each piece to see if it contains a piece or is empty foreach (Row row in rows) foreach (char piece in row.Pieces) if (piece == emptyPiece) return false; // if we get this far, it's a tie return true; } // this function checks to see if there is a winner static bool CheckForWin(Row[] rows, char playerCharacter) { // four in a row is a win string playerString = new string(playerCharacter, 4); // first check for a horizontal win (the easiest kind) foreach (Row row in rows) if (new string(row.Pieces).Contains(playerString)) return true; // next check for a vertical win string[] columns = new string[ColumnCount]; foreach (Row row in rows) for (int i = 0; i < ColumnCount; i++) columns += row.Pieces; foreach (string column in columns) if (column.Contains(playerString)) return true; // finally, check for a diagonal win. this is the hardest kind string[] diagonals = new string[ColumnCount + RowCount - 1]; for (int i = 0; i < ColumnCount + RowCount - 1; i++) diagonals = ""; int offset = RowCount - 1; foreach (Row row in rows) { for (int i = 0; i < ColumnCount; i++) diagonals[offset + i] += row.Pieces; offset--; } foreach (string diagonal in diagonals) if (diagonal.Contains(playerString)) return true; // otherwise, no win was found return false; } }}
It keeps telling me not all code paths return a value. Can anyone tell me why please? The code looks fine to me.
public static int Row(int n) { // makes sure pieces are not replacing opponent // players pieces by returning spot for piece to fall columns[n] -= 1; while (still2) { if (columns[n] < 0) { Console.WriteLine("Column is Full try another one"); Proj6.printBoard(); continue; } else { return columns[n]; } } }
What is 'still2'? How can its value change? If it did change, and the loop wasn't exited, where would the code be? (Answer: at the end of the function, and there's no return value there.)
The problem is that you're trying to handle the "tell the user he's an idiot" logic in the same function that detects his idiocy. In programming this tends not to work very well. You need to communicate back to the calling code that the user's selected column is full, and handle the loop there. Pay careful attention to Mike.Popolowski's addPiece() function for an example of how code is normally structured to handle this sort of thing.
The problem is that you're trying to handle the "tell the user he's an idiot" logic in the same function that detects his idiocy. In programming this tends not to work very well. You need to communicate back to the calling code that the user's selected column is full, and handle the loop there. Pay careful attention to Mike.Popolowski's addPiece() function for an example of how code is normally structured to handle this sort of thing.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement