Access violation reading location 0x0000001 - c++

I have this function in c++ that should add a member to a linked list, but when it's executed it throw an exception:
Unhandled exception at 0x5b9414cf (msvcr100d.dll) in Sample.exe: 0xC0000005: Access violation reading location 0x00000001
This happen when some variable isn't definite...but I can't figure out where is this variable...also with breakpoints.
Here the entire code (except for the .h file...but it only contains declaration)
#include "stdafx.h"
#include "winsock.h"
#include "windows.h"
#include <string.h>
#include <iostream>
#include "Sample.h"
using namespace std;
struct BUNNY
{
public:
int sex;
int name;
int age;
bool colour;
int radioactive_mutant_vampire_bunny;
BUNNY *nextBunny;
};
int returnSex();
int returnName (int sex);
int returnColour ();
bool radioactiveBunny ();
string translateName(int name);
string translateSex(int sex);
string translateColour(int colour);
BUNNY * AddBunny(BUNNY * head,int sex,int name,int colour,bool radioactive_mutant_vampire_bunny);
BUNNY * travereseBunny(BUNNY * head);
BUNNY * displayBunny();
int _tmain(int argc, _TCHAR* argv[])
{
bool flag = true;
int turn = 0;
BUNNY * head = new BUNNY;
head = NULL;
while (flag)
{
++turn;
if (turn == 1)
{
for (int i = 1; i <= 5; i++)
{
int sex = returnSex();
int name = returnName(sex);
int colour = returnColour();
bool radioactive = radioactiveBunny();
head = AddBunny(head,sex,name,colour,radioactive);
printf("A new bunny is born: sex %s , name %s , colour %s , radioactive %d",head->sex,head->name,head->colour,head->radioactive_mutant_vampire_bunny);
system("pause");
}
}
}
return 0;
}
int returnSex()
{
int random = rand() % 100 + 1;
if(random > 50)
return MALE;
else
return FEMALE;
}
int returnName(int sex)
{
if (sex == MALE)
{
int random = (rand() % 100 + 1) / 5;
if(random < 20)
return BU;
else if (random > 20 && random <40)
return CRYSTAL;
else if(random > 40 && random < 60)
return JASON;
else if(random > 60 && random < 80)
return ERO;
else if(random > 80)
return METH;
}
else
{
int random1 = rand() % 100 + 1;
if (random1 < 50 )
{
return MARIA;
}
else if (random1 > 50)
return JAMIE;
}
}
int returnColour ()
{
int random = rand() % 4 + 1;
if(random == 1)
return WHITE;
else if(random > 1 && random <= 2)
return BROWN;
else if(random > 2 && random <= 3)
return BLACK;
else if(random > 3 && random <= 4)
return SPOTTED;
}
bool radioactiveBunny()
{
int random = rand() % 100 + 1;
if(random > 0 && random <= 2)
return true;
else
return false;
}
BUNNY * AddBunny(BUNNY * head,int sex,int name,int colour,bool radioactive_mutant_vampire_bunny)
{
BUNNY * newBunny = new BUNNY;
newBunny->age = 0;
newBunny->colour = colour;
newBunny->sex = sex;
newBunny->name = name;
newBunny->radioactive_mutant_vampire_bunny = radioactive_mutant_vampire_bunny;
newBunny->nextBunny = head;
return newBunny;
}
string translateName (int name)
{
switch (name)
{
case CRYSTAL: return "CRYSTAL";
break;
case BU: return "BU";
break;
case JASON: return "JASON";
break;
case ERO: return "ERO";
break;
case METH: return "METH";
break;
case MARIA: return "MARIA";
break;
case JAMIE: return "JAMIE";
break;
}
}
string translateColour (int colour)
{
switch (colour)
{
case WHITE: return "WHITE";
break;
case BLACK: return "BLACK";
break;
case BROWN: return "BROWN";
break;
case SPOTTED: return "SPOTTED";
break;
}
}
string translateSex (int sex)
{
switch (sex)
{
case MALE: return "MALE";
break;
case FEMALE: return "FEMALE";
break;
}
}
this is the entire code...hope it will help.
thanks for your time :)

Whether there is a probelm or no depends on how you call the function
It should be called the following way
head = AddBunny( /* some arguments */ );
If you call it such a way then there is no problem with the function.
If you call it as for example
AddBunny( /* some arguments */ );
that is without assigning head by the returning pointer then head will be always equal to NULL.
EDIT: After you showed additional code then I would like to point out that these statements
BUNNY * head = new BUNNY;
head = NULL;
are invalid. There is a memory leak. You at first allocate memory and head gets the address of the memory and then you reassign the head.
There must be
BUNNY * head = NULL;
Also it seems your code has a typo. You defined private data members as
bool colour;
int radioactive_mutant_vampire_bunny;
but corresponding parameters of function AddBunny are defined diffirently
BUNNY * AddBunny(BUNNY * head,int sex,int name,int colour,bool radioactive_mutant_vampire_bunny);
The abend was due to incorrect formating symbol. You defined colour as bool but trying to output it as a string literal.
printf("A new bunny is born: sex %s , name %s , colour %s , radioactive %d",head->sex,head->name,head->colour,head->radioactive_mutant_vampire_bunny);
You wrote colour %s while head->colour has type bool
By the way the address 0x00000001 shown in the message
Access violation reading location 0x00000001
is the value of colour that is equal to boolean literal true that is to 1.

Your problem is the printf statement, consider the following:
printf("Test: %s", 2);
This will produce a crash, as printf is assuming a string, but you pass an integer. The integer will thus be interpreted as char* and therefor result in an access violation as soon as printf tries to print any char (which requires dereferencing the pointer).
But this is exactly what happens if you do:
printf("A new bunny is born: sex %s", head->sex);
As BUNNY::sex is declared as int.

Related

when i try to compile i keep getting message vector subscript out of range

string getName() { return name; }
string getE1() { return enemy1; }
string getE2() { return enemy2; }
string getE3() { return enemy3; }
bool isEnemy(string check) {
if (check == enemy1 || check == enemy2 || check == enemy3)
//if the name being checked is an enemy of this knight
return true;
else
return false;
}
int Candidate(Knight b) {//'b' is an enemy of 'a' who is in the seat before 'b'(ie. b seat=2 a seat=1
int toSwap = b.seatingPos;//toSwap holds seating pos # of 'b'
int checkFriends = (toSwap - 1);//holds seating pos of 'a'
string nameA = table[checkFriends].getName();
for (int i = 0; i < 8; i++) {
if (table[i].isEnemy(nameA) || table[i].getName() == nameA) //if not enemies, then must be friends
{
continue;
}
else
{
friends.push_back(table[i].seatingPos);
}//adds seating # of friends of 'a' to friends vector
}
for (int j = 0; j < 4; j++) {//check friends of 'a' to see if their neighbor is friends with 'b'
int check2 = table[friends[j]].seatingPos;//check 2 holds seating pos # of 'c'
if (check2 != 7)
++check2;
else
return check2;
if ((table[toSwap].isEnemy(table[check2].getName()))) //if neighbor of c is friends with b(toSwap)
{
continue;
}
else {
return check2;//if not enemies then must be friends return seating pos of acceptable candidate
}
}
return 0;
}
when i debug the code it says i have an unhandled exception when assigning
string nameA = table[checkFriends].getName();
the value of checkfriends = 0 so it shouldnt be out of the range of the vector.
debugger also says: Unhandled exception at 0x7BC8F2F6 (ucrtbased.dll) in Knights.exe: An invalid parameter was passed to a function that considers invalid parameters fatal. occurred
this occurs during the 1st if statement.
thanks for any help!!!

Why does my c++ code run fine on Windows 7 but crashes on Windows 8?

Ok, I added the following code to a mod menu for a game and everything works fine for me in Windows 7. But when I send it to my friend on Windows 8, he tries to select a button (which calls the GetClients() function) and the game just crashes. Any idea why?
char* playerNames[31] = {};
int getUID(char* pName)
{
int i = 0;
while (i < 31) {
char* pNamesec = (char*)PLAYER::GET_PLAYER_NAME((Player)(i));
if (pNamesec == pName) {
return i;
}
//else { break; }
i++;
}
}
char* getPnameAt(int id) {
for (int i = 0; i < 30; i++) {
if (i == id) {
return (char*)PLAYER::GET_PLAYER_NAME((Player)(i));
}
}
}
void GetClients()
{
playerNames[31] = {};
int i = 0;
while (i < 100) {
char* pName = (char*)PLAYER::GET_PLAYER_NAME((Player)(i));
if (wcslen((WCHAR*)pName) > 3) {
if (getUID(pName) == i) {
playerNames[i] = pName;
} else {
getPnameAt(i);
}
}
i++;
}
i = 0;
}
Error message that pops up says:
CORE: An exception occurred while executing modmenu.asi, press ok to continue
You have created an array of length 31. So you can access array playerName from index 0 to index 30. In GetClients()
playerNames[31] = {}; //Observe this line
while (i < 100) {
// Indexes greater than 30 are being used to access playerNames array
}
31 or beyond is not a valid index for playerNames array and you are getting undefined behavior.
So if you want to add in playerNames in runtime. Below is the small example that might help you..
int main()
{
vector<string> playerNames;
playerNames.push_back("XYZ");
playerNames.push_back("ABC");
// To access from vector
vector<string>::iterator itr = vec.begin();
for(;itr!=vec.end();itr++)
{
cout<<*itr<<endl;
}
}
Read more here

Access violation writing location 0x000001C0

I'm working on this and have a problem that I cant figure out.
I got this in the header
class PGEnemy : Public CCSprite
{
private:
int pHP;
int pLoot;
int pAttack;
int pSpeed;
PGEnemy();
~PGEnemy();
public:
bool setSpeed (int speed);
static PGEnemy* factory(eType type); //create an enemy
void init(int type); //read info from json (json cpp)
};
And in the code I got this
void PGEnemy::init(int type)
{
try
{
Reader reader;
Value initial;
unsigned long size = 0;
unsigned char *config_doc = CCFileUtils::sharedFileUtils()->getFileData("enemy.json", "r", &size);
bool parsingSuccessful = reader.parse((char*)config_doc, initial);
string s = TO_STRING(type);
cout << s << endl;
if(parsingSuccessful)
{
this->pHP = initial[TO_STRING(type)]["hp"].asInt();
this->pLoot = initial[TO_STRING(type)]["loot"].asInt();
this->pAttack = initial[TO_STRING(type)]["attack"].asInt();
this->pSpeed = initial[TO_STRING(type)]["speed"].asInt();
}
}
catch (exception)
{
this->pHP = 100*type;
this->pAttack = 100*type;
this->pSpeed = 100*type;
this->pLoot = 100*type;
}
//*/
}
In the moment of doing this->pHP = initial[TO_STRING(type)]["hp"].asInt();
or any other that I shall put a value in those integers (even in the catch), it crash with the error
Access violation writing location 0x000001C0.
from a open source code for using json, file Json_value.cpp
Value::asInt() const
{
switch ( type_ )
{
case nullValue:
return 0;
case intValue:
JSON_ASSERT_MESSAGE( value_.int_ >= minInt && value_.int_ <= maxInt, "unsigned integer out of signed int range" );
return Int(value_.int_);
case uintValue:
JSON_ASSERT_MESSAGE( value_.uint_ <= UInt(maxInt), "unsigned integer out of signed int range" );
return Int(value_.uint_);
case realValue:
JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" );
return Int( value_.real_ );
case booleanValue:
return value_.bool_ ? 1 : 0;
case stringValue:
case arrayValue:
case objectValue:
JSON_FAIL_MESSAGE( "Type is not convertible to int" );
default:
JSON_ASSERT_UNREACHABLE;
}
return 0; // unreachable;
}
The most "unknow" is that the error also happened when I simply try to do this->pHP = anyIntegerValue
PGEnemy* PGEnemy::factory(eType type)
{
PGEnemy* enemy = (PGEnemy*)CCSprite::create("Target.png");
enemy->init(type);
return enemy;
}

access violation reading location c++

I'm writing a program that print the full english name of the number inputted by the user. it's not a complete program but i keep getting an error:
First-chance exception at 0x00b02c76 in Programming Challenge 14.1.exe: 0xC0000005: Access violation reading location 0xcccccd80.
Unhandled exception at 0x00b02c76 in Programming Challenge 14.1.exe: 0xC0000005: Access violation reading location 0xcccccd80.
I've tried looking around and couldn't find anything of use to me. here this the program:
header file:
#ifndef NUMBERS_H
#define NUMBERS_H
#include <string>
using namespace std;
const int SIZE1 = 18;
const int SIZE2 = 8;
class Numbers
{
private:
int number;
string hundred;
string thousand;
string * one;
string * ten;
public:
Numbers(int num)
{
number = num;
hundred = "hundred";
thousand = "thousand";
string * one = new string[SIZE1];
string * ten = new string[SIZE2];
}
void initializeArray()
{
// Intialize array "one"
one[0] = "zero";
one[1] = "one";
one[2] = "two";
one[3] = "three";
one[4] = "four";
one[5] = "five";
one[6] = "six";
one[7] = "seven";
one[8] = "eight";
one[9] = "nine";
one[10] = "eleven";
one[11] = "twelve";
one[12] = "thirteen";
one[13] = "fourteen";
one[14] = "fifteen";
one[15] = "sixteen";
one[16] = "seventeen";
one[17] = "eighteen";
one[18] = "nineteen";
// Initialize the ten array
ten[0] = "ten";
ten[1] = "twenty";
ten[2] = "thirty";
ten[3] = "forty";
ten[4] = "fifty";
ten[5] = "sixty";
ten[6] = "seventy";
ten[7] = "eighty";
ten[8] = "ninety";
}
string determine()
{
string name = "";
for (int i = 0; i <= number; i++)
{
if (number == i)
{
name = one[i];
}
}
return name;
}
~Numbers()
{
delete [] one;
delete [] ten;
}
};
#endif
and this is the main program, im just using a constructor to assign a value to number to make debugging a little faster
#include <iostream>
#include "Numbers.h"
using namespace std;
int main()
{
Numbers n(5);
string name = n.determine();
cout << "The number is " << name << endl;
cin.ignore();
cin.get();
return 0;
}
by the way this is vc++ for the compiler
ill answer any questions as this isnt really too organized
const int SIZE1 = 18;
Valid array index for the array of SIZE1 are 0 to 17. In general, valid indexes for an array of size N are 0 to N-1.
I recommend using std::vector<std::string>.
one holds 18 elements, but you put 19 elements in there.
Two things here:
You are not calling "initializeArray()" at all. So when you are trying to access the array there is nothing there. I would recommend calling it in the constructor. Like this:
Numbers(int num)
{
number = num;
hundred = "hundred";
thousand = "thousand";
one = new string[SIZE1];
ten = new string[SIZE2];
initializeArray();
}
Second, is what the guys above said. You have an incorrect value for the size of your array since you are trying to assign 19 values to an array of size 18. Just to be really sure lets make the size bigger than we expect and you can adjust later:
const int SIZE1 = 20;
const int SIZE2 = 20;
Additionally, See your determine()? instead of using a for loop why don't you go:
string name = one[number];
EDIT: Wow there was another thing I missed...you have declared your array pointer variable twice and so it's actually going out of scope thinking you want to make some local versions. Look at my adjusted implementation of your constructor above again. See how I've removed the "String *" from before the variable names.
The variable "one" and "ten" have been changed from string pointers to vectors holding strings. Called the initializeArray within the constructor. Changed the way the name string was being assigned the new string. Here is the working code.
class Numbers
{
private:
int number;
string hundred;
string thousand;
vector<string> one;
vector<string> ten;
public:
Numbers(int num)
{
number = num;
hundred = "hundred";
thousand = "thousand";
initializeArray();
}
void initializeArray()
{
one.push_back("zero");
one.push_back("one");
one.push_back( "two");
one.push_back("three");
one.push_back("four");
one.push_back("five");
one.push_back("six");
one.push_back("seven");
one.push_back("eight");
one.push_back("nine");
one.push_back("eleven");
one.push_back("twelve");
one.push_back("thirteen");
one.push_back("fourteen");
one.push_back("fifteen");
one.push_back("sixteen");
one.push_back("seventeen");
one.push_back("eighteen");
one.push_back("nineteen");
// Initialize the ten array
ten.push_back("ten");
ten.push_back("twenty");
ten.push_back("thirty");
ten.push_back("forty");
ten.push_back("fifty");
ten.push_back("sixty");
ten.push_back("seventy");
ten.push_back("eighty");
ten.push_back("ninety");
}
string determine()
{
string name("");
for (int i = 0; i <= number; i++)
{
if (number == i)
{
auto iter = one.begin();
iter += i;
name.assign(*iter);
}
}
return name;
}
~Numbers()
{
}
};
int main()
{
Numbers n(5);
string name = n.determine();
cout << "The number is " << name << endl;
cin.ignore();
cin.get();
return 0;
}

Linking/Integration Issue. I need a direction of where to go?

So I have a 2 games running side by side.
proj2/main.cpp (main that gets run that then can call either game)
proj2/spades/display.cpp
proj2/spades/gameplay.cpp
proj2/spades/otherFiles.cpp
proj2/hearts/display.cpp (this is the same display class as in the spades game with the same functions just sightly altered.)
proj2/hearts/hearts.cpp
proj2/hearts/otherFiles.cpp
What basically happened is I am trying to integrate 2 games, 1 I created and another that uses the same display.cpp and display.h files slightly altered. In order to do this I created 2 seperate namespaces, hearts and spades. Everything I have compiles fine but a few of the .cpp files do not link correctly and I get errors such as the following.
./gamePlay.o: In function `__static_initialization_and_destruction_0(int, int)':
gamePlay.cpp:(.text+0x396): undefined reference to `spades::display::display()'
./gamePlay.o: In function `__tcf_3':
gamePlay.cpp:(.text+0x480): undefined reference to `spades::display::~display()'
./gamePlay.o: In function `spades::gamePlay::storeBid(std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)':
gamePlay.cpp:(.text+0x1507): undefined reference to `spades::display::captureInput()'
What am I doing wrong here?
Below are some of the files I am using. Let me know if there are anymore I should add. (Dont want to bloat this post anymore than I have to)
gameplay.cpp
#include <iostream>
#include <sys/ioctl.h>
#include <cstdio>
#include <unistd.h>
#include <locale.h>
#include <ncursesw/ncurses.h>
#include <fstream>
#include "gamePlay.h"
#include <cstdlib>
#include <sstream>
#include <ctime>
namespace spades {
vector <spades::player> players(4);
vector <spades::card> deck(52);
spades::display monitor;
spades::card center[4];
vector <spades::card> gamePlay::getDeck(){return deck;}
vector <spades::player> gamePlay::getplayers(){return players;}
//sorts the cards in the players hand into diamonds, clubs, hearts, spades
void gamePlay::handSort(){
int spades[13];
int hearts[13];
int clubs[13];
int diamonds[13];
int index;
int i;
for(i=0; i<13; i++){ //determines the card number and places them into corresponding indexes
index = (players.at(0).hand.at(i).getCardNum()+11)%13; //cause the cards to be placed based on their number with 2 being index 0 and 1(ace) being index 12
switch(players.at(0).hand.at(i).getSuit())
{
case 1: spades[index] = 1;
break;
case 2: hearts[index] = 1;
break;
case 3: clubs[index] = 1;
break;
case 4: diamonds[index] = 1;
break;
default: mvprintw(3,2,"!!!!!!!we have a problem!!!!!!!!!!");
break;
}
}
i = 0;
while(i<13){ //being placing the ordered cards back into the players hand
int j = 0;
while(j < 13){
if(diamonds[j] == 1){ //if a card has been placed in this index for the diamonds only array
if(j+2 == 14) //if the card is an ace
players.at(0).hand.at(i).setCardNum(1);
else
players.at(0).hand.at(i).setCardNum(j+2); //add 2 to each index to get the card number
players.at(0).hand.at(i).setSuit(4);
i++;
}
j++;
}
j = 0;
while(j < 13){
if(clubs[j] == 1){
if(j+2 == 14)
players.at(0).hand.at(i).setCardNum(1);
else
players.at(0).hand.at(i).setCardNum(j+2);
players.at(0).hand.at(i).setSuit(3);
i++;
}
j++;
}
j = 0;
while(j < 13){
if(hearts[j] == 1){
if(j+2 == 14)
players.at(0).hand.at(i).setCardNum(1);
else
players.at(0).hand.at(i).setCardNum(j+2);
players.at(0).hand.at(i).setSuit(2);
i++;
}
j++;
}
j = 0;
while(j < 13){
if(spades[j] == 1){
if(j+2 == 14)
players.at(0).hand.at(i).setCardNum(1);
else
players.at(0).hand.at(i).setCardNum(j+2);
players.at(0).hand.at(i).setSuit(1);
i++;
}
j++;
}
}
}
//compares the center pile of 4 played cards to determine who wins the trick
int gamePlay::compareCenter(int leadplayer){
int highest = center[leadplayer].getCardNum();
if(center[leadplayer].getCardNum() == 1)
highest = 14;
int suit = center[leadplayer].getSuit();
int player = leadplayer;
for(int i = leadplayer+1; i < leadplayer+4; i++)
{
if(center[i%4].getSuit() == 1)
setSpadesBroken(true);
if((suit != 1) && (center[i%4].getSuit() == 1))
{
player = i%4;
suit = 1;
highest = center[i%4].getCardNum();
}
if(suit == center[i%4].getSuit()){
if(center[i%4].getCardNum() == 1){
player = i % 4;
highest = 14;
}
if(highest < center[i%4].getCardNum())
{
player = i%4;
highest = center[i%4].getCardNum();
}
}
}
players.at(player).setTricksTaken(players.at(player).getTricksTaken()+1); //increments the trick count of the winning player
return player; //return the player who won to determine who goes first next turn
}
//Create the deck of 52 cards by setting the suit and number of each card to a nonzero integer
void gamePlay::createDeck() {
for(int j = 0; j < 52; j++)
{
deck.at(j).setCardNum((j%13)+1);
deck.at(j).setSuit((j/13)+1);
}
random_shuffle(deck.begin(), deck.end());
}
//deal out 13 cards to each player by setting the
void gamePlay::deal(vector <spades::card> &newdeck, vector <spades::player> &newplayers){
for(int i = 0; i<52; i++){
newplayers.at(i/13).addCard(newdeck.at(i));
newdeck.at(i).setSuit(0);
newdeck.at(i).setCardNum(0);
}
}
//determines if the player still has a card of the same suit in their hand as the leading card played
bool gamePlay::containSuit(spades::card lead, spades::player players){
bool suit = false;
for(int i = 0; i < players.getHand().size(); i++){
if(lead.getSuit() == players.getHand().at(i).getSuit())
suit = true;
}
return suit;
}
//determines if the player has only spades cards left in their hand
bool gamePlay::onlySpade(spades::player play){
for(int i = 0; i<play.getHand().size(); i++){
if(play.getHand().at(i).getSuit()!=1)
return false;
}
return true;
}
//determines if the position the player is clicking on the screen actually points to a playable card
//and then returns the position of that card based on the player's hand vector of type <card>
int gamePlay::handCheck(int xevent, int yevent, vector <spades::player> players, int trickStart){
int i = xevent/6;
//first check to find the card on the display
if(i>=0 && i<players.at(0).getHand().size() && yevent>17 && yevent<23 &&
players.at(0).getHand().at(i).getSuit() != 0 &&
players.at(0).getHand().at(i).getCardNum() != 0)
{
spades::card playedCard = players.at(0).getHand().at(i);
//check to see if leading the current round or not and if spades are "broken"
if(trickStart==0 && !getSpadesBroken()){
if(onlySpade(players.at(0)))
return i;
else if(playedCard.getSuit() != 1)
return i;
else
return (-1);
}
if(trickStart == 0 && getSpadesBroken())
return i;
//if not leading, then call the containsuit method to see if your hand contains one of similar suit
if(trickStart > 0 && containSuit(center[trickStart],players.at(0))){
if(playedCard.getSuit()==center[trickStart].getSuit())
return i;
}
if(trickStart > 0 && !containSuit(center[trickStart],players.at(0)))
return i;
else
return (-1);
}
mvprintw(4,3,"invalid card");
return (-1);
}
//draws the cards in the player's hand if it contains a valid card, erase the card otherwise if invalid
void gamePlay::displayHand(){
int offset = 0;
for(int i =0; i<players.at(0).getHand().size(); i++){
if(players.at(0).getHand().at(i).getSuit() != 0)
monitor.displayCard(offset, 17, players.at(0).getHand().at(i).getSuit(), players.at(0).getHand().at(i).getCardNum(), 0);
else
monitor.eraseBox(offset, 17, 6, 5);
offset+=6;
}
}
void gamePlay::displayAdd(){
vector <string> lines;
int count12 = 0;
string line;
ifstream myfile ("advertisement.txt");
if ( myfile.is_open() )
{
while ( ! myfile.eof() )
{
getline (myfile, line);
lines.push_back(line);
count12++;
}
myfile.close();
int random1 = rand() % 6;
monitor.bannerBottom(lines.at(random1));
}
else{
monitor.bannerBottom("Unable to open Advertisement file.");
}
}
//determins the position of a mouse click and sends that to handcheck(), and then sends the card to the center pile array to be scored
void gamePlay::humanPlay(int trickStart){
int xevent, yevent;
for(;;){
mvprintw(3,2,"Please choose a card to play.");
int key = monitor.captureInput();
// if a mouse click occurred
if (key == -1) {
xevent = monitor.getMouseEventX();
yevent = monitor.getMouseEventY();
int handCh = handCheck(xevent, yevent, players, trickStart);
if(handCh != (-1)){ //if the card is valid
spades::card played = players.at(0).getHand().at(handCh);
players.at(0).hand.at(handCh).setCardNum(0);
players.at(0).hand.at(handCh).setSuit(0);
center[0]= played;
monitor.displayCard(39, 12, center[0].getSuit(), center[0].getCardNum(), 0);
displayHand();
//playedCards++; //Update Global Variable---- NEED TO HAVE THIS INITIATED GLOBALLY.
break;
}
else
mvprintw(4,3,"invalid card");
}
}
}
//loops through a computer players hand and checks to see if the random card is playable within the rules of the game
void gamePlay::CPUplay(int trickStart, int CPU){
bool goodCard = false;
spades::card playedCard =players.at(CPU).getHand().at(0);
int i;
for(i = 0; i < players.at(CPU).getHand().size(); i++){
if(players.at(CPU).getHand().at(i).getSuit() != 0 &&
players.at(CPU).getHand().at(i).getCardNum() != 0){
playedCard = players.at(CPU).getHand().at(i);
//check to see if leading or not
if(trickStart==CPU && !getSpadesBroken()){
if(onlySpade(players.at(CPU)))
break;
if(playedCard.getSuit()!=1)
break;
}
if(trickStart == CPU && getSpadesBroken())
break;
//if not leading use contains suit function
if(trickStart != CPU && containSuit(center[trickStart], players.at(CPU)))
if(playedCard.getSuit()==center[trickStart].getSuit())
break;
if(trickStart != CPU && !containSuit(center[trickStart], players.at(CPU)))
break;
}
}
players.at(CPU).hand.at(i).setCardNum(0);
players.at(CPU).hand.at(i).setSuit(0);
center[CPU]= playedCard;
if(CPU==1)
monitor.displayCard(29, 7, center[CPU].getSuit(), center[CPU].getCardNum(), 0);
if(CPU==2)
monitor.displayCard(39, 2, center[CPU].getSuit(), center[CPU].getCardNum(), 0);
if(CPU==3)
monitor.displayCard(49, 7, center[CPU].getSuit(), center[CPU].getCardNum(), 0);
}
//scores each team with the player being teamed with CPU 2 and the other team being CPU 1 and CPU 3
void gamePlay::score(spades::player &play, spades::player &play2){
int trickOver = play.getTricksTaken()-play.getBid(); // Calculate the difference between bid and actually taken.
if(play.getBid() == NULL)
trickOver = 0;
int trickOver2 = play2.getTricksTaken()-play2.getBid(); // Calculate the difference between bid and actually taken.
int totalBid = play.getBid()+play2.getBid();
int totalTrick = trickOver+trickOver2;
//Bidding Double Nil (if gets it 200 points other wise -200 points)
if(play.getDoubleNil()){
if(play.getTricksTaken()==0) //player did get Double Nil successfully
play.setScore(play.getScore()+200); // add 200 points
else
play.setScore(play.getScore()-200);
}
else if(play.getBid()==0){ //Bidding Nil (if gets it 100 points other wise -100 points)
if(play.getTricksTaken()==0) //player did get Nil successfully
play.setScore(play.getScore()+100); //add 100 points
else //player didnt get Nil
play.setScore(play.getScore()-100); //take away 100 points
}
if(totalTrick < 0){ //player bids more than number of tricks won
play.setScore(play.getScore()+(totalBid*(-10))); //decrease score by 10 poitns for every overtrick
}
else if(totalTrick >= 0){ //player bids less then number of tricks won
play.setSandBag(play.getSandBag() + totalTrick); //increase sandbag by 1
play.setScore(play.getScore()+totalTrick+(10*totalBid)); //increase 10 points per trick bid on and 1 point per trick over
}
if(play.getSandBag()>10){ //check for sandbagging
play.setScore(play.getScore()-100);
play.setSandBag(play.getSandBag()-10);
}
play.setBid(NULL); //reset players bid to NULL
play2.setBid(NULL); //reset players bid to NULL
play.setTricksTaken(0);
play2.setTricksTaken(0);
play.setDoubleNil(false); //Player has not yet bid double NILL.
}
//loops infinitely until a mouse click or key input is detected, then sets bid accordingly
void gamePlay::storeBid(stringstream &msg){
int xevent;
int yevent;
for(;;){
mvprintw(3,2,"Click the box bid Double Nil or type out your bid now. \n Use the keys 1-9, a for 10, b for 11, c for 12, and d for 13.");
int key = monitor.captureInput();
monitor.drawBox(2, 5, 3, 2, 0);
xevent = monitor.getMouseEventX();
yevent = monitor.getMouseEventY();
if (key == -1)
if((xevent>=2 && xevent<4)&&(yevent>=5 && yevent <7)){
msg.str("");
msg << "Your bid: double nil";
monitor.bannerTop(msg.str());
players.at(0).setDoubleNil(true);
break;
}
else{
msg.str("");
msg << "Your bid is horrible. Bid again!!!!";
monitor.bannerTop(msg.str());
}
if ((key-48) >= 0 && (key-48) <= 9){
msg.str("");
msg << "Your bid: " << (key-48);
monitor.bannerTop(msg.str());
players.at(0).setBid(key-48);
break;
}
else if(key>=97 && key<=100){
msg.str("");
msg << "Your bid: " << (key-87);
monitor.bannerTop(msg.str());
players.at(0).setBid(key-87);
break;
}
else if(key!=0 && key!=-1){
msg.str("");
msg << "Your bid is horrible. Bid again!!!!";
monitor.bannerTop(msg.str());
}
}
monitor.eraseBox(1, 1, 62, 16);
}
//main function that runs the entire game
void gamePlay::runGame(){
double startTime = clock();
stringstream messageString;
srand(time(NULL));
int count;
int handStart = 0;
int trickStart;
while(players.at(0).getScore()<500 && players.at(1).getScore()<500)
{
createDeck();
deal(deck, players); //deal out 13 cards to each player
handSort(); // sort the human players hand
displayHand();
storeBid(messageString); //asks for bid
//sets the bid randomly between 2-4 for each computer player
players.at(1).setBid(rand()%3+2);
players.at(2).setBid(rand()%3+2);
players.at(3).setBid(rand()%3+2);
//displays the current bid and scores of each team
messageString << " Partner: " << (players.at(2).getBid())
<< " CPU 1: " << players.at(1).getBid()
<< " CPU 3: " << players.at(3).getBid()
<< " Team Score = " << players.at(0).getScore()
<< " Enemy Score = " << players.at(1).getScore();
monitor.bannerTop(messageString.str());
displayAdd();
trickStart = handStart;
count = 0;
setSpadesBroken(false);
while(count<13){ // simulates the different cases where the human player plays 1st, 2nd, 3rd, last
bool success = true;
switch (trickStart)
{
case 0: humanPlay(trickStart);
CPUplay(trickStart,1);
CPUplay(trickStart,2);
CPUplay(trickStart,3);
break;
case 3: CPUplay(trickStart,3);
humanPlay(trickStart);
CPUplay(trickStart,1);
CPUplay(trickStart,2);
break;
case 2: CPUplay(trickStart,2);
CPUplay(trickStart,3);
humanPlay(trickStart);
CPUplay(trickStart,1);
break;
case 1: CPUplay(trickStart,1);
CPUplay(trickStart,2);
CPUplay(trickStart,3);
humanPlay(trickStart);
break;
default: mvprintw(3,2,"!!!!we have a problem!!!!");
success = false;
break;
}
monitor.eraseBox(3, 2, 20, 2);
for(;;){//pause to wait for an acknowledgment mouse click
int key = monitor.captureInput();
monitor.eraseBox(3, 2, 30, 4);
mvprintw(3,2,"click anywhere to continue");
if(key == -1){
break;
}
}
//if no errors appear, display the tricks taken
if(success){
monitor.eraseBox(1, 1, 62, 16);
trickStart = compareCenter(trickStart);
messageString.str("");
messageString << "Your Tricks= " << players.at(0).getTricksTaken()
<< " Partner= " << players.at(2).getTricksTaken()
<< " CPU 1= " << players.at(1).getTricksTaken()
<< " CPU 3= " << players.at(3).getTricksTaken();
displayAdd();
monitor.bannerAboveBottom(messageString.str());
count++;
}
}
//score the round and tally up for each team
for(int n =0; n<2;n++)
score(players.at(n),players.at(n+2));
messageString.str("");
monitor.bannerTop(messageString.str());
messageString << "Your Tricks = " << players.at(0).getTricksTaken()
<< " Partner = " << players.at(2).getTricksTaken()
<< " CPU 1 = " << players.at(1).getTricksTaken()
<< " CPU 3 = " << players.at(3).getTricksTaken();
handStart = (handStart +1) % 4;
}
double endTime = clock();
}
}
gameplay.h
#include "player.h"
#include "display.h"
#ifndef gamePlay_H
#define gamePlay_H
namespace spades {
using namespace std;
class gamePlay{
bool spadesBroken;
public:
vector <spades::card> getDeck();
vector <spades::player>getplayers();
bool getSpadesBroken() {return spadesBroken;}
void setSpadesBroken(bool b){spadesBroken = b;}
int compareCenter(int leadplayer);
void createDeck();
void deal(vector <spades::card> &deck, vector <spades::player> &players);
void handSort();
bool containSuit(spades::card lead, spades::player players);
bool onlySpade(spades::player play);
int handCheck(int xevent, int yevent, vector <spades::player> players, int trickStart);
void displayHand();
void displayAdd();
void humanPlay(int trickStart);
void CPUplay(int trickStart, int CPU);
void score(spades::player &play, spades::player &play2);
void storeBid(stringstream &msg);
void runGame();
};
}
#endif
player.h
#include <iostream> // Stream declarations
#include <vector> //Vectors used to store deck and players hands
#include <string> //String declarations
#include <algorithm> //Shuffle Method
#include "card.h"
#ifndef PLAYER_H
#define PLAYER_H
namespace spades {
using namespace std;
class player {
int score; //total score
int bid; //bid for that round
int tricksTaken; //score for thast round
int sandBag; //the number of points you win, more than what you bid, every 10th bag = -100
bool doubleNil;
//vector <card> hand;
public:
player();
vector <card> hand;
int getSandBag(){return sandBag;}
bool getDoubleNil() {return doubleNil;}
int getScore() {return score;}
int getBid() {return bid;}
int getTricksTaken() {return tricksTaken;}
vector<card> getHand() {return hand;}
void setSandBag(int i) {sandBag = i;}
void setBid(int i) {bid = i;}
void setTricksTaken(int i) {tricksTaken=i;}
void setScore(int i) {score = i;}
void setDoubleNil(bool i) {doubleNil = i;}
//add card to end of vector
void addCard(card b);
void removeCard(card a);
};
}
#endif
player.cpp
#include <iostream> // Stream declarations
#include <vector> //Vectors used to store deck and players hands
#include <string> //String declarations
#include <algorithm> //Shuffle Method
#include <sys/ioctl.h>
#include <cstdio>
#include <unistd.h>
#include <locale.h>
#include <ncursesw/ncurses.h>
#include "player.h"
namespace spades {
using namespace std;
player::player() {
score =0; //total score
bid = NULL; //bid for that round
tricksTaken = 0; //score for thast round
sandBag = 0; //the number of points you win, more than what you bid, every 10th bag = -100
doubleNil = false;
for(int i=0; i<13; i++)
hand.push_back(card());
}
void player::addCard(spades::card b){
for (int i=0; i<hand.size(); i++){
//compare card being played to the ones in your hand to search and determine which one to erase
if((hand.at(i).getCardNum() == 0) &&
(hand.at(i).getSuit() == 0))
{
hand.at(i).setCardNum(b.getCardNum());
hand.at(i).setSuit(b.getSuit());
return;
}
}
}
void player::removeCard(spades::card a) {
for (int i=0; i<hand.size(); i++){
//compare card being played to the ones in your hand to search and determine which one to erase
if((hand.at(i).getCardNum() == a.getCardNum()) &&
(hand.at(i).getSuit() == a.getSuit()))
{
hand.at(i).setCardNum(0);
hand.at(i).setSuit(0);
return;
}
}
}
}
What does your link line look like? It looks like when you're linking, you're missing spades.o?
If that's not it, use the nm command to see what symbols spades.o is providing - it's always possible
you've typo'd a namespace name or something:
nm -C spades.o | grep 'display::.*display'
(The -C option should put nm into C++/demangled mode - if it doesn't for your nm, add a "c++filt" or "dem" step to the pipe chain before grep).