This is a simple tic-tac-toe game as I'm sure you've seen, the code is incomplete. I don't need somebody to look over all of it, just how to format the 2-D character array before '.empty' so that I know how to access it as a reference. If you can take a look at inside the "int get_row()", that'd be great.
I've already tried everything that my textbook and C++ tutorials tell me, and I"m pretty sure none of them have 2-D arrays as part of the exercises. I mean, I can't find it, if you can send a link that'd be nice.
#include <iostream>
#include <string>
#include <array>
using namespace std;
char board[3][3];
void print_board(char board[3][3])
{
cout << " 0 1 2 " << endl;
cout << "0 " << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << " " << endl;
cout << " -----------" << endl;
cout << "1 " << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << " " << endl;
cout << " -----------" << endl;
cout << "2 " << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << " " << endl;
}
void clear_board(char board[][3])
{
}
int get_row(char board[][3], char player)
{
int row;
cout << "Please enter the row move for player " << player << endl;
cin >> row;
if (board.empty())
return row;
}
int get_column(char board[][3], char player)
{
int column;
cout << "Please enter the column move for player " << player << endl;
cin >> column;
return column;
}
bool check_win(char board[][3], char player)
{
return true;
}
bool board_full(char board[][3])
{
return true;
}
bool square_occupied(char board[][3],int row,int column)
{
return true;
}
void get_move(char board[3][3], char player)
{
do
{
do {
int row, column;
get_row(board, player);
get_column(board, player);
square_occupied(board, row, column);
} while (square_occupied);
board_full(board);
} while (!board_full);
}
int main()
{
string play_again = "Y", answer;
int row, column;
char player = 'X';
cout << "Welcome to tic-tac-toe!" << endl;
cout << "Please, use the coordinates for rows and columns to record moves." << endl;
do {
do {
print_board(board);
board_full(board);
get_move(board, player);
check_win(board, player);
if (player == 'X')
{
player = 'O';
}
else
{
player = 'X';
}
} while (!check_win);
cout << "Would you like to play again? (Y/N)";
cin >> answer;
}while (answer == play_again);
return 0;
}
I just want to be able to check if the array container at [row] is going to be empty or not. I really just can't use reference arrays, that's all.
If you declare a C-array, it's never empty (and also it doesnt have aempty` member function).
char board[3][3]; //Never empty - always has 9 values
Of course, a Tic Tac Toe board can be empty. The array representing the board isn't empty, but the values in the array are probably set to either 0 or some other value that indicates that they're empty.
We can write a small class to represent the board, and give it a empty function:
struct Board {
char board[3][3];
Board() : board() {}
bool empty() const {
char* data = &board[0][0];
for(int i = 0; i < 9; i++) {
if(data[i] != 0) return false;
}
return true;
}
bool rowEmpty(int row) const {
return board[row][0] == 0 && board[row][1] == 0 && board[row][2] == 0;
}
bool colEmpty(int col) const {
return board[0][col] == 0 && board[1][col] == 0 && board[2][col] == 0;
}
void putX(int row, int col) {
board[row][col] = 'X';
}
void putO(int row, int col) {
board[row][col] = 'O';
}
// This function returns a reference so you can modify it if you want
char& getSquare(int row, int col) {
return board[row][col];
}
};
By creating a class to represent the board, you can add whatever functionality and member functions you want!
Related
The game does not want to exit/close. Somebody enlighten me as to what I've missed? Also, do you think i have coded the game properly?
Source code:
#include<iostream>
#include<iomanip>
using namespace std;
void drawBoard(char board[][3]);
char checkWinner3by3(char board[][3]);
int main()
{
char board[3][3] = {{' ',' ',' '},{' ',' ',' '},{' ',' ',' '}};
int row;
int column;
bool is_move;
bool is_row;
bool is_column;
cout<<"********** TIC TAC TOE ************\n";
{
is_move = false;
is_row = false;
is_column = false;
drawBoard(board);
cout << "Player ";
if(player == 'X')
{
cout << 1;
}
else
{
cout << 2;
}
cout << "'s turn:" << endl;
is_move = false;
while(!is_move)
{
while(!is_row)
{
cout << "Row: ";
cin >> row;
if(row == 1 || row == 2 || row == 3)
{
is_row = true;
}
else
{
cout << endl << "Invalid row!" << endl;
}
}
/
is_column = false;
while(!is_column)
{
cout << "Column: ";
cin >> column;
if(column == 1 || column == 2 || column == 3)
{
is_column = true;
}
else
{
cout << endl << "Invalid column!" << endl;
}
}
Irrelevant stuff here.
if(board[row-1][column-1] == ' ')
{
board[row-1][column-1] = player;
is_move = true;
if(player == 'X')
{
player = 'O';
}
else
{
player = 'X';
}
}
else
{
cout<<"The selected space is occupied!" << endl;
cout << "Select a different space:" << endl << endl;
drawBoard(board);
}
}
cout << endl;
Checking the winner
winner = checkWinner3by3(board);
if(winner == 'X' || winner == 'O')
{
drawBoard(board);
cout<<"Congratulations! Player ";
if(winner == 'X')
{
cout << 1;
}
else
{
cout << 2;
}
cout<<" is the winner!"<<endl;
}
else if(winner == 'T')
{
drawBoard(board);
cout << "It's a tie!" << endl;
}
}
system("pause");
return 0;
}
Board is here.
void drawBoard(char board[][3])
{
char print[][3] = {{' ',' ',' '},
{' ',' ',' '},
{' ',' ',' '}};
cout << " 1 2 3" << endl;
cout << " +---+---+---+" << endl;
cout << " 1" << " | " << print[0][0] << " | " << print[0][1] << " | "
<< print[0][2] << " | " << endl;
cout << " +---+---+---+" << endl;
cout << " 2" << " | " << print[1][0] << " | " << print[1][1] << " | "
<< print[1][2] << " | " << endl;
cout << " +---+---+---+" << endl;
cout << " 3" << " | " << print[2][0] << " | " << print[2][1] << " | "
<< print[2][2] << " | " << endl;
cout << " +---+---+---+" << endl;
}
char checkWinner3by3(char board[][3])
{
for(i=0; i<3; i++)
{
if(board[i][0]==board[i][1] && board[i][0]==board[i][2])
{
return board[i][0];
}
}
for(i=0; i<3; i++)
{
if(board[0][i]==board[1][i] && board[0][i]==board[2][i])
{
return board[0][i];
}
}
if(board[0][0]==board[1][1] && board[1][1]==board[2][2])
{
return board[0][0];
}
if(board[0][2]==board[1][1] && board[1][1]==board[2][0])
{
return board[0][2];
}
return ' ';
}
This is the entire source code - i wanted to make a game and i honestly think this is the best way to start by knowing what i can do to improve it.
You have not declared the variable "player" & "winner" yet have initialized them...but this could be because the full code is not displayed.
you have system("pause") before return... why did you put that there?
...now that I look further its all screwed up
I made a Tic-Tac-Toe once and it's kinda similar to what your trying to do apart from selection via 2d array, you should consider using parts of it to correct your code.
#include <iostream>
#include <iomanip>
using namespace std;
char* cBox{ new char[9]{ '1', '2', '3', '4', '5', '6', '7', '8', '9' } }; // cBox are tic tac toe squares
char* PcBox{ nullptr }; // PcBox will be pointers to cBox squares
bool EndGame{ true }, VailidMove{ true }, WinGame{ true }; // Global bool varibles are initially set to true to test for validity
size_t PlayerMove{ 1 };
int Move;
int score(size_t PlayerMove); /********************************/
void Board(); /* */
void error(); /* Function Prototypes */
void GameOver(); /* */
int scoreboard(int score1, int score2); /********************************/
int main() {
int score1{}, score2{};
int sum{};
int winner{};
int const total{ 756 };
char PlayerIcon;
// do while loop
do {
// print scoreboard
scoreboard(score1, score2);
// Print board
Board();
// This conditional forces the first Player to be 'X'... Player2 'O'
(PlayerMove == 1) ? PlayerIcon = 'X' : PlayerIcon = 'O';
// Time for the player to move
cout << endl << setw(51) << "Player" << PlayerMove << "'s move:";
cin >> Move;
VailidMove = false; // ValidMove is assigned to false within the "do loop"...it will remain false until a valid key is entered..
//... it's conditionally tested within the while loop until the player's move is true(valid)
// Loop until we get a valid move
while (!VailidMove) {
system("CLS"); // Clear the screen
(PcBox = &cBox[Move - 1]); // For our move selection, point PcBox to the address of the array cBox[index] on the free store
if (!(*PcBox == 'X' || *PcBox == 'O') && (cin) && Move != 0) // this checks the location for PlayerIcons...as one cannot place a new playericon where one already resides...
// ...also tests whether a legit key input..aka not a "letter" or a "0"
{
VailidMove = true;
*PcBox = PlayerIcon; // A valid playericon is placed in a free box on the board
}
else
{
error(); // Anything else other than a valid selection will throw an error and return to the beginning of the block...
return main(); // ...querying the player for a valid selection until one is entered
}
};
EndGame = false; // Again like "VailidMove" we set EndGame to false to test against the following conditions
// This is a combintion of seperate win conditions... 3 the same, across or diagonal over entire board
if (cBox[0] == cBox[1] && cBox[1] == cBox[2])
GameOver();
if (cBox[0] == cBox[4] && cBox[8] == cBox[4])
GameOver();
if (cBox[1] == cBox[4] && cBox[7] == cBox[4])
GameOver();
if (cBox[2] == cBox[4] && cBox[6] == cBox[4])
GameOver();
if (cBox[2] == cBox[8] && cBox[5] == cBox[8])
GameOver();
if (cBox[3] == cBox[0] && cBox[6] == cBox[0])
GameOver();
if (cBox[3] == cBox[4] && cBox[5] == cBox[4])
GameOver();
if (cBox[6] == cBox[8] && cBox[7] == cBox[8])
GameOver();
// If the board is full and no one wins then it is a tie...this piece just sums up all the player icons as ascii integers...
// ...if the board is full of them, then the sum is 756 and it is a tie.
sum += (*PcBox); // add player icon to sum...Ascii to int
if ((sum == total) && !EndGame) // if sum of playericon for entire board = 756...no win
{
EndGame = true;
WinGame = false;
sum = 0; //reset sum to zero
scoreboard(score1, score2);
}
// End/Win game conditions
if (EndGame) { // game over? test choices
if (WinGame) { // We nest this here soley if EndGame & WinGame is true... else if just WinGame is true its a draw
if (PlayerMove == 1) { score1 = score(PlayerMove); }
if (PlayerMove == 2) { score2 = score(PlayerMove); }
scoreboard(score1, score2);
winner = PlayerMove;
}
Board();
if (WinGame)
cout << "\n" << setw(51) << "PLAYER " << winner << " WINS!" << endl;
cout << endl << setw(57) << "Game Over!!!" << endl;
cout << endl << setw(59) << "Play again y/n?"; // Query the player for another game
char PlayAgain;
cin >> PlayAgain;
// This resets the board, if the player wants another game, it uses a for loop to increment simultaneously it's "ascii integer", along side it's "int" equivalent...
//... overwriting & reseting the board from 1-9 with the original characters
if (PlayAgain == 'y' || PlayAgain == 'Y') {
EndGame = false;
for (int i = 0, j = 49; i < 9 && j <= 57; i++, j++) // ASCII int 49 = char '1'... to 57 = char '9'
{
(cBox[i] = (char)j); // Clear the board
}
sum = 0; // Reset sum to zero
system("CLS"); // Clear the screen
}
PlayerMove = 1;
if (PlayAgain == 'n') {
EndGame = true;
}
}
else
{
(PlayerMove == 1) ? PlayerMove = 2 : PlayerMove = 1;
}
} while (!EndGame);
delete[] cBox; // Free up memory...
cBox = nullptr;
cout << "\n\t\t\t\t\t";
return 0;
}
// Function definiton to print game board
inline void Board() {
{
cout << endl << '\n' << '\n' << endl;
cout << setw(50) << cBox[0] << "|" << cBox[1] << "|" << cBox[2] << endl;
cout << setw(54) << "-+-+-" << endl;
cout << setw(50) << cBox[3] << "|" << cBox[4] << "|" << cBox[5] << endl;
cout << setw(54) << "-+-+-" << endl;
cout << setw(50) << cBox[6] << "|" << cBox[7] << "|" << cBox[8] << endl;
}
}
// Function definiton to keep score
int score(size_t PlayerMove)
{
int static score1{ 1 };
int static score2{ 1 };
if (PlayerMove % 2)
return score1++;
else
return score2++;
}
// Function definiton to print scoreboard
int scoreboard(int score1, int score2)
{
cout << endl << setfill(' ') << setw(47) << "PLAYER 1: " << score1 << " " << "PLAYER 2: " << score2;
return(score1, score2);
}
// Function definiton to throw an error
void error() {
{
cout << setfill(' ') << setw(64) << "Invalid Move. Try again." << endl;
cin.clear(); //clear the error flags.
cin.ignore(); //sync up the stream in case the user entered white space
}
}
// Function definiton to end game
void GameOver()
{
EndGame = true;
}
This question already has answers here:
Using fstream Object as a Function Parameter
(3 answers)
Closed 6 years ago.
#include <bits/stdc++.h>
using namespace std;
class contact {
private:
vector< pair<string, int> > contact_info;
public:
void add_contact(string contact_name, int contact_number) {
contact_info.push_back(make_pair(contact_name, contact_number));
sort(contact_info.begin(),contact_info.end());
}
void edit_contact(string contact_name) {
int found_at;
for (unsigned int i =0; i < contact_info.size(); i++) {
if (contact_info[i].first == contact_name) {
found_at = i;
}
}
if (contact_info[found_at +1].first == contact_name) {
int choice;
int counter = found_at;
int index = 1;
while (contact_info[counter].first == contact_name) {
cout << index << ". " << contact_info[counter].first << " " << contact_info[counter].second;
counter++;
index++;
}
cout << "Choose any please: ";
cin >> choice;
found_at = found_at - (choice - 1);
}
cout << "Enter the new number: ";
cin >> contact_info[found_at].second;
}
void show_all() {
for (unsigned int i =0; i < contact_info.size(); i++) {
cout << contact_info[i].first << " " << contact_info[i].second << endl;
}
}
void delete_contact(string contact_name) {
int found_at;
for (unsigned int i =0; i < contact_info.size(); i++) {
if (contact_info[i].first == contact_name) {
found_at = i;
}
}
if (contact_info[found_at +1].first == contact_name) {
int choice;
int counter = found_at;
int index = 1;
while (contact_info[counter].first == contact_name) {
cout << index << ". " << contact_info[counter].first << " " << contact_info[counter].second;
counter++;
index++;
}
cout << "Choose any please: ";
cin >> choice;
found_at = found_at - (choice - 1);
}
contact_info.erase(contact_info.begin()+found_at);
}
void writeFile(ofstream contact_file) {
for (unsigned int i =0; i < contact_info.size(); i++) {
contact_file << contact_info[i].first << " " << contact_info[i].second << endl;
}
}
void readFile(ifstream contact_file) {
string input;
while (!contact_file.eof()) {
contact_file >> input;
size_t pos = input.find(" ");
string name = input.substr(0,pos);
string number_str = input.substr(pos);
int number = stoi(number_str) ;
contact_info.push_back(make_pair(name,number));
}
}
};
int main()
{
int choice;
ifstream contacts_file_read;
contacts_file_read.open("contacts.txt");
ofstream contacts_file_write;
contacts_file_write.open("contacts.txt");
bool in_prog = true;
contact contacts;
string name;
int number;
while (in_prog) {
cout << "1. Add contacts" << endl
<< "2. Edit contact" << endl
<< "3. Delete contact" << endl
<< "4. Show all" << endl
<< "5. exit" << endl;
cout << "Your choice: ";
cin >> choice;
contacts.readFile(contacts_file_read);
if (choice == 1) {
cout << "Enter name & number separated by a space: ";
cin >> name >> number;
contacts.add_contact(name, number);
} else if (choice == 2) {
cout << "Enter name of contacts to be edited: ";
cin >> name;
contacts.edit_contact(name);
} else if (choice == 3) {
cout << "Enter name of contact to be deleted: ";
cin >> name;
contacts.delete_contact(name);
} else if (choice == 4) {
contacts.show_all();
} else if(choice == 5) {
contacts.writeFile(contacts_file_write);
} else {
cout << "Wrong choice" << endl;
}
}
return 0;
}
So, I was asked in my programming class to make a phone book application in C++ using only objects, so this is my attempt at it.
All functions are good, I did recompile the program after finishing each function at it gave me 0 errors, however whenever I try to call writeFile or readFile function that were previously working fine, now the compiler gave me an error of "error: use of deleted functions... "
I don't know what are deleted functions and why only functions that take file objects as an argument are treated as such.
Can anyone please help?
Thanks.
Objects of type std::ifstream are not copyable -- indeed, the object represents the unique handle of an open file, and it would be difficult to conceptualize what it would mean to copy such unique responsibility.
Indeed, this inability to copy an object is encoded by making the copy constructor deleted, which causes the error that you see when you do attempt to copy it.
Your code should pass the original ifstream, not a copy (by taking a reference parameter):
void readFile(ifstream & contact_file)
// ^^^^^^^^^^
I've been assigned by school to create an application that contains a book list with 20 different books in it and build a menu with following options:
(a) List – Display the list in tabular format. Each display should contain an appropriate heading and column captions;
(b) Search – Search for a book record in the list using the ISBN and print the full record for the book;
(c) Delete – Delete an existing book record from the list;
(d) Exit – Stop the program.
Here is the sample of my program:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <cctype>
using namespace std;
typedef struct
{
char code[50];
char author[50];
char name[50];
char edition[50];
char publish[50];
char price[50];
} BOOK_LIST;
void list (BOOK_LIST book[], int rows);
void showBook (BOOK_LIST book[], int rows);
void updateRecord (BOOK_LIST book[], int rows);
void advancedSearch (BOOK_LIST book[], int rows);
int deleteBook (BOOK_LIST book[], int rows);
int searchBook(BOOK_LIST book[], int rows);
int main()
{
ifstream inFile("list.txt");
if(!inFile)
cout << "Error opening input file\n";
else
{
BOOK_LIST books[50];
int index = -1, choice;
inFile.getline(books[++index].code, 50);
while(inFile)
{
if(inFile.peek() == '\n')
inFile.ignore(256, '\n');
inFile.getline(books[index].author, 50);
inFile.getline(books[index].name, 50);
inFile.getline(books[index].edition, 50);
inFile.getline(books[index].publish, 50);
inFile >> books[index].price;
// read next number
inFile >> books[++index].code;
}
inFile.close();
// menu starts
do
{
cout << "Do you want to:\n";
cout << "1. List all books\n";
cout << "2. Get details about a book\n";
cout << "3. Delete a book from the list\n";
cout << "4. Exit\n";
cout << "5. Advanced Search\n";
cout << "Enter choice: ";
cin >> choice;
switch (choice)
{
case 1 : list(books, index);
break;
case 2 : showBook(books, index);
break;
case 3 : updateRecord(books, index);
break;
case 5 : advancedSearch(books, index);
case 4 : break;
default: cout << "Invalid choice\n";
}
} while (choice != 4);
ofstream outFile("list.txt");
if(!outFile)
cout << "Error opening output file, records are not updated.\n";
else
{
for (int i = 0; i < index; i++)
{
outFile << books[i].code << endl;
outFile << books[i].author << endl;
outFile << books[i].name << endl;
outFile << books[i].edition << endl;
outFile << books[i].publish << endl;
outFile << books[i].price << endl;
}
outFile.close();
}
}
return 0;
}
void list(BOOK_LIST book[], int rows)
{
cout << fixed << setprecision(2);
cout << "ISBN\t Author BookName Edition\tPublisher\t Price\n";
for (int i = 0; i < rows; i++)
cout << book[i].code << "\t" << book[i].author << "\t"
<< book[i].name << "\t" << book[i].edition << "\t"
<< book[i].publish << "\t"
<< " " << book[i].price << endl;
return;
}
int searchBook(BOOK_LIST book[], int rows)
{
int i = 0;
bool found = false;
char code[50];
cout << "Enter an ISBN code of a book to search: ";
fflush(stdin);
cin.getline(code, 50);
while (i < rows && !found)
{
if (strcmp(code, book[i].code) == 0)
found = true;
else
i++;
}
if (found)
return i;
else
return -1;
}
void showBook(BOOK_LIST book[], int rows)
{
int pos = searchBook(book, rows);
if (pos != -1)
{
cout << "Author is " << book[pos].author << endl;
cout << "Book name is "<< book[pos].name << endl;
cout << book[pos].edition << " Edition" << endl;
cout << "The publisher of this book is " << book[pos].publish << endl;
cout << "Current price is " << book[pos].price << endl;
}
else
cout << "Product not found\n";
return;
}
void updateRecord(BOOK_LIST book[], int rows)
{
int pos = deleteBook(book, rows);
char code [50];
int i,j = 0;
for(i = 0; i < rows ; i++)
{
if(strcmp(code, book[i].code))
{
strcpy(book[j].code , book[i].code);
strcpy(book[j].author, book[i].author);
strcpy(book[j].name, book[i].name);
strcpy(book[j].edition, book[i].edition);
strcpy(book[j].publish, book[i].publish);
strcpy(book[j].price, book[i].price);
j++;
}//if
else
{
i++;
strcpy(book[j].code, book[i].code);
strcpy(book[j].author, book[i].author);
strcpy(book[j].name, book[i].name);
strcpy(book[j].edition, book[i].edition);
strcpy(book[j].publish, book[i].publish);
strcpy(book[j].price, book[i].price);
j++;
}//else
}//for
return;
}
int deleteBook (BOOK_LIST book[], int rows)
{
int i = 0;
bool found = false;
char code[50];
cout << "Enter an ISBN code of a book to delete: ";
fflush(stdin);
cin.getline(code, 50);
while (i < rows && !found)
{
if (strcmp(code, book[i].code) == 0)
found = true;
else
i++;
}
if (found)
return i;
else
return -1;
}
void advancedSearch (BOOK_LIST book[], int rows)
{
char advanced[50];
cout << "Please enter either the author's name or the book name to search: ";
fflush(stdin);
cin.getline(advanced, 50);
for(int i = 0; i < rows; i++)
{
if(strstr(book[i].author, advanced) || strstr(book[i].name, advanced))
{
cout << "ISBN is " << book[i].code << endl;
cout << "Author is " << book[i].author << endl;
cout << "Book name is " << book[i].name << endl;
cout << book[i].edition << " Edition" << endl;
cout << "Publisher is " << book[i].publish << endl;
cout << "Current price is " << book[i].price << endl;
}
}
return ;
}
The problem starts here:
When I want to permanently delete a whole row of book record. But the book record is still there after deleting.
First, this is my menu, then I press 1 to check the list for the IBSN. Then, I press 3 to proceed to the deleting part. At that time, I choose TheHost to delete. After the deleting, to ensure that I have deleted the chosen book, so I press 1 to check the list again, but unfortunately the book is still there:
If I am able to delete a book record, and how do I delete a record permanently? And after deleting a record, how do I move the remaining records upwards, so that it won't leave any empty row there?
The function for the deleting:
void updateRecord(BOOK_LIST book[], int rows)
{
int pos = deleteBook(book, rows);
char code [50];
int i,j = 0;
for(i = 0; i < rows ; i++)
{
if(strcmp(code, book[i].code))
{
strcpy(book[j].code , book[i].code);
strcpy(book[j].author, book[i].author);
strcpy(book[j].name, book[i].name);
strcpy(book[j].edition, book[i].edition);
strcpy(book[j].publish, book[i].publish);
strcpy(book[j].price, book[i].price);
j++;
}//if
else
{
i++;
strcpy(book[j].code, book[i].code);
strcpy(book[j].author, book[i].author);
strcpy(book[j].name, book[i].name);
strcpy(book[j].edition, book[i].edition);
strcpy(book[j].publish, book[i].publish);
strcpy(book[j].price, book[i].price);
j++;
}//else
}//for
return;
}
The Text file that I used in this program a.k.a the BOOK_LIST
I see (at least) two problems with your code around deleting a book.
in update_record you're using a char code[50] which is being used to compare with strcmp later on but is not initialized.
when you delete a book you should update your index which becomes rows in the update_record method. However index is passed to rows by value which means that even if you try running --rows; in update_record it won't decrement index. You'll need to pass it by reference for it to update index.
On a side note, I agree with comments regarding fixing your code to use vectors/maps & strings instead of simple arrays and char*.
But since you mentioned it was a school task I would guess you haven't reached that sort of material yet.
Good Luck.
The assignment most probably expects you to use std::list template rather than the classical C array. Insertion and deletion is natural for lists.
An alternative would be to use std:map using the ISBN as a key. ISBN is supposed to be globally unique.
Just to expand on my comment, here is one way to remove an element from an array.
Suppose we have an array of char called X, containing {'a', 'b', 'c', 'd', 'e', 'f'}, and we want to get rid of 'c'.
If we want to maintain the order of the remaining elements, then what we're aiming for is {'a', 'b', 'd', 'e', 'f'}. So we copy the 'd' into the 'c' place, the 'e' into the old 'd' place, and so on:
a b c d e f
a b d d e f
a b d e e f
a b d e f f
We can do this with code like
for(int k=2; k<5; ++k)
X[k] = X[k+1];
And what happens to that extra 'f' at the end? We could write some placeholder into that unwanted space, and then watch out for that placeholder for the rest of the run. Or, we could just stop using that space, and say that from now on we're considering an array of length 5. That extra 'f' will still be there, but for now we don't care about what exists past the end of our array.
(If we don't care about the order of the remaining elements, then we can make this a lot simpler.)
Remember, it's always easier to develop new functionality in isolation.
Once you have this working, you can apply it in your code and get a passing grade, but if you really want to learn something useful you should write a Book class.
//Benjamin McKinney
//CSCI 2010-10
//Spring 2015
//PASS 3
//Programmed on Windows 8.1 using Visual C++ 2010 Express
//This program plays the game MasterMind
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
struct Player
{
string Name;
int HighScores[6];
bool CheatOn;
};
struct Board
{
int NumHoles;
int Holes[6];
};
struct Guess
{
int Count;
int NumHoles;
int Holes;
};
void printHighScores(string);
void readHighScore(string);
void updateHighScore(string, int);
string getPlayer();
int getBoard();
void playGame(string);
void menu(string);
int main()
{
Player p;
srand((unsigned int)time(0));
cout << "!!! Benjamin McKinney's Master-MasterMind!!!\n";
cout << "--------------------------------------------\n";
getPlayer();
menu(p.Name);
cout << "Goodbye, " << p.Name << endl;
printHighScores(p.Name);
cout << "----------------------------------------------\n";
cout << "!!! Benjamin McKinney's Master-MasterMind!!!\n";
system("PAUSE");
return 0;
}
void printHighScores(string name)
{
return;
}
void readHighScore(string)
{
return;
}
void updateHighScore(string, int)
{
return;
}
string getPlayer()
{
Player p;
cout << "What is your name?\n";
cin >> p.Name;
cout << "Welcome, " << p.Name << endl;
p.CheatOn = false;
readHighScore(p.Name);
return p.Name;
}
int getBoard()
{
Board b;
cout << "Enter the number of holes you would like: ";
cin >> b.NumHoles;
if(b.NumHoles > 6 || b.NumHoles < 1)
{
cout << "Error! You must pick a number between 1 and 6! Try again!\n";
}
for(int i=0;i<b.NumHoles;i++)
{
b.Holes[i] = rand() % 2 + 1;
}
return b.NumHoles;
}
void playGame(string)
{
Player p;
Board b;
Guess g;
getBoard();
g.Count=0;
for(int i=0;i<b.NumHoles;i++)
{
cout << "Enter your guess for the row\n";
if(p.CheatOn == true)
{
for(int a=0;a<(sizeof(b.Holes)-1);a++)
{
cout << b.Holes[a];
}
}
cout << "Enter your guess for hole " << i << ": ";
cin >> g.Holes;
g.Count++;
}
return;
}
void menu(string)
{
Player p;
char choice;
cout << "Please choose an option below:\n";
cout << "\t P)lay\n\t Q)uit\n\tChoice: ";
cin >> choice;
if(choice == 'P')
playGame(p.Name);
else
if(choice == 'Q')
return;
else`enter code here`
if(choice == 'C')
{
p.CheatOn = true;
playGame(p.Name);
}
}
Ignore the three HighScore functions, but otherwise I can't get this to work... "Run-Time Check Failure #3 - The variable 'b' is being used without being initialized." is the main issue that I'm having. If anyone can help me I would really appreciate it. Thanks!
In the playGame function:
void playGame(string)
{
Player p;
Board b; // <----- uninitialized
// ...
for(int i=0;i<b.NumHoles;i++)
// ^^^^^^^^^^
you use b.NumHoles when you have never initialized b.
I guess you intended that getBoard() would magically have some effect on b but it doesn't. The getBoard function updates a local board but never does anything with it.
To fix this you could change getBoard to return the whole board:
Board getBoard()
{
Board b;
// set up b...
return b;
}
and then inside playGame:
Board b = getBoard();
There's another error just below:
for(int a=0;a<(sizeof(b.Holes)-1);a++)
The sizeof operator gives the size in bytes. You actually want the size in elements, so you need to divide by the element size:
a < (sizeof b.Holes / sizeof b.Holes[0])
I'm not sure what the -1 was meant to be doing either, this would just cause you to not output the last hole.
Hello i am making a tic tac toe game in console.
What's wrong with my code?
I Got linker settings set as console.
code:
// Tic tac Toe
// Plays a tic tac toe game against a npc
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
// global constants
const char X = 'X';
const char O = '0';
const char EMPTY = ' ';
const char TIE = 'T';
const char NO_ONE = 'N';
//function prototypes
void instructions();
char askYesNo(string question);
int askNumber(string question, int high, int low =0);
char humanPiece();
char opponent(char piece);
void displayBoard(const vector<char>& board);
char winner(const vector<char>& board);
bool isLegal(const vector<char>& board, int move);
int humanMove(const vector<char>& board, char human);
int computerMove(const vector<char>& board, char computer);
void announceWinner(char winner, char computer, char human);
int main()
{
int move;
const int NUM_SQUARES = 9;
vector<char> board(NUM_SQUARES, EMPTY);
instructions();
char human = humanPiece();
char computer = opponent(human);
char turn = X;
displayBoard(board);
while (winner(board) == NO_ONE)
{
if (turn == human)
{
move = humanMove(board, human);
board[move] = human;
}
else
{
move = computerMove(board, computer);
board[move] = computer;
}
displayBoard(board);
turn = opponent(turn);
}
announceWinner(winner(board), computer, human);
return 0;
}
void instructions()
{
cout << "Welcome to the ultimate man-machine showdown: Tic Tac Toe.\n";
cout << "--I'm gonna cut you in half like a knife and butter like a lightsaber and steel!!!\n\n";
cout << "make your move now by entering a number, 0-8. The number\n";
cout << "corresponds to the desired board position , as illustrated: \n\n";
cout << " 0|1|2 \n";
cout << " ------- \n";
cout << " 3|4|5 \n";
cout << " ------- \n";
cout << " 6|7|8 \n\n";
cout << "Prepare yourself human, the battle is about to begin.\n\n";
}
char askYesNo(string question)
{
char response;
do
{
cout << question << "(y\n): ";
cin >> response;
}while (response != 'y' && response != 'n');
return response;
}
int askNumber(string question, int high, int low)
{
int number;
do
{
cout << question << "(" << low << "-" << high << "): ";
cin >> number;
}while (number > high || number < low);
return number;
}
char humanPiece()
{
char go_first = askYesNo("Do you require the first move?");
if (go_first == 'y')
{
cout << "\n Then take the first move. You will need it.\n";
return X;
}
else
{
cout << "Then I will make the first move.\n";
return 0;
}
}
char opponent(char piece)
{
if (piece == 'X')
{
return X;
}
else
{
return 0;
}
}
void displayBoard(const vector<char>& board)
{
cout << "\n\t" << board[0] << "|" << board[1] << "|" << board[3];
cout << "\n\t" << "-------";
cout << "\n\t" << board[3] << "|" << board[4] << "|" << board[5];
cout << "\n\t" << "-------";
cout << "\n\t" << board[6] << "|" << board[7] << "|" << board[8];
cout << "\n\n";
}
char winner(const vector<char>& board)
{
// all possible winning rows
const int WINNING_ROWS[8][3] = {{0,1,2},
{3,4,5},
{6,7,8},
{0,3,6},
{1,4,7},
{2,5,8},
{0,4,8},
{2,4,6}};
const int TOTAL_ROWS = 8;
// if any winning row has three values wich are the same(and not EMPTY)
// then we have a winner
for (int row = 0; row < TOTAL_ROWS; ++row)
{
if ((board[WINNING_ROWS[row][0]] != EMPTY) && (board[WINNING_ROWS[row][0]] == board[WINNING_ROWS[row][1]]) && (board[WINNING_ROWS[row][1]] == board[WINNING_ROWS[row][2]]))
{
return board[WINNING_ROWS[row][0]];
}
}
//since nobody has won check for a tie (no empty squares left)
if (count(board.begin(), board.end(), EMPTY) == 0)
{
return TIE;
}
//since nobody has won and it isn't a tie, the game ain't over
return NO_ONE;
}
inline bool isLegal(int move, const vector<char>& board)
{
return (board[move] == EMPTY);
}
int humanMove(const vector<char>& board, char human)
{
int move = askNumber("Where will you move?", (board.size() - 1));
while (!isLegal(move, board))
{
cout << "\n That square is already occupied, foolish human.\n" << endl;
int move = askNumber("Where will you move?", (board.size() - 1));
}
cout << "Fine....\n";
return move;
}
int computerMove(vector<char> board, char computer)
{
unsigned int move = 0;
bool found = false;
//if the pc can win on next move I will take that move
while (!found && move < board.size())
{
if (isLegal (move, board))
{
board[move] = computer;
found = winner(board) == computer;
board[move] = EMPTY;
}
if (!found)
{
++move;
}
}
// otherwise if the human can win with the next move that's the move I will make
if (!found)
{
move = 0;
char human = opponent(computer);
while (!found && move < board.size())
{
if (isLegal(move, board))
{
board[move] = human;
found = winner(board) == human;
board[move] = human;
}
if (!found)
{
++move;
}
}
}
// otherwise i'll be moving to the next best square
if (!found)
{
move = 0;
unsigned int i = 0;
const int BEST_MOVES[] = {4,0,2,6,8,1.3,5,7};
// pick best open square
while (!found && i < board.size())
{
move = BEST_MOVES[i];
if (isLegal(move, board))
{
found = true;
}
++i;
}
}
cout << "I shall take square number" << move << endl;
return move;
}
void announceWinner(char winner, char computer, char human)
{
if (winner == computer)
{
cout << winner << "has won!\n";
cout << "As I predicted human, I am triumphant once more!\n";
}
else if (winner == human)
{
cout << winner << "has won" << endl;
cout << "no, no it cannot be! Somehow you tricked me Human!\n";
}
else
{
cout << "It's just a tie, I'll beat you next time! \n";
cout << "You cannot beat me though!";
}
}
The forward declaration of -
int computerMove(const vector<char>& board, char computer);
is different from the actual implementation. ( Misses the const part )
int computerMove(vector<char> board, char computer)