Reputation: 382
So I'm trying to create a program that mimics the Minesweeper game. I have double-checked the header files, the class names, and made sure the headers are #included in the other cpp files, but when I try to build the program, I get a LNK2019 error in the "Main" class I have.
Error in full:
Error 1 error LNK2019: unresolved external symbol "public: __thiscall Board::Board(int,int,int)" (??0Board@@QAE@HHH@Z) referenced in function _main \fpsb\g\gathmr26\visual studio 2013\Projects\Minesweeper\Minesweeper\Main.obj Minesweeper
I've spent probably around 2 hours looking at answers here on StackOverflow and elsewhere and got nowhere. I've run down through every bullet point in this MSDN page, and every "common cause" in this popular answer, and none of them seemed to apply to my situation. I've also tried all the "Diagnosis tools" options on the MSDN page and all they've done is just confuse me more.
The closest I have to my situation (as far as I can tell) is this question except that all of my code is just in one project, not multiple. One of the people who answered that question has said "I typed this code into my Visual Studio and it worked fine", having assumed that the files were in one project. I don't understand why that answer got it working there when I have pretty much the same situation here.
So, anyway, here is the code:
Main.cpp
#include <iostream>
#include <string>
#include "Cell.h"
#include "Board.h"
int main() {
Board *bee;
bee = new Board(50, 50, 50);
std::cout << "board created";
return 0;
}
Board.cpp
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
using namespace std;
#include "Cell.h"
#include "Board.h"
#ifndef BOARD_H
#define BOARD_H
// Board class. Used to create an array of cell objects to function as data model for Minsweeper game.
class Board
{
private:
int width; // number of columns in board
int height; // number of rows in board
int mines; // number of mines stored in board
Cell*** cells; // array storing cell objects
public:
// Constructor for board. Takes number of columns, rows, and mines as parameters
Board::Board(int cols, int rows, int numMines) {
width = cols;
height = rows;
mines = numMines;
cells = new Cell**[height];
for (int i = 0; i < height; i++) {
cells[i] = new Cell*[width];
}
int c = 0;
int r = 0;
while (r < height)
{
while (c < width)
{
setCell(c, r, CellValue::COVERED_CELL);
c++;
}
c = 0;
r++;
}
int m = 0;
while (m < numMines)
{
std::srand(std::time(nullptr));
int x = generateRandomNumberInRange(0, width - 1);
int y = generateRandomNumberInRange(0, height - 1);
if (!(getCellVal(x, y) == MINE))
{
setCell(x, y, CellValue::MINE);
m++;
}
}
}
// Accessor for width field
int Board::getWidth()
{
return width;
}
// Accessor for height field
int Board::getHeight()
{
return height;
}
// Accessor for mines field
int Board::getMines()
{
return mines;
}
// Function to access value of cell located in array where x is column parameter and y is row parameter
CellValue Board::getCellVal(int x, int y)
{
CellValue value = CellValue::INVALID_CELL;
if (!(x < 0 || x >(width - 1) || y < 0 || y >(height - 1)))
{
Cell temp = *cells[x][y];
value = temp.getValue();
}
return value;
}
// Function to set value of cell located in array where x is column parameter and y is row parameter
void Board::setCell(int x, int y, CellValue value)
{
if (!(x < 0 || x >(width - 1) || y < 0 || y >(height - 1)))
{
Cell temp = *cells[x][y];
temp.setValue(value);
}
}
// Function to determine if game is lost
// Loops through array to see if there are any UNCOVERED_MINES
// If so, returns true, game ends, as you've lost :(
// If not, returns false and game can continue
// Should run after every click action in game
bool Board::isGameLost()
{
bool isLost = false;
int c = 0;
int r = 0;
while (r < height)
{
while (c < width)
{
if (getCellVal(c, r) == UNCOVERED_MINE)
{
isLost = true;
}
c++;
}
c = 0;
r++;
}
return isLost;
}
// Function to determine if game is won
// Loops through array to determine if there are any falsely flagged mines, unflagged mines, covered cells, or uncovered mines
// If there are, returns false and game continues
// If not, returns true, games ends, you've won :)
bool Board::isGameWon()
{
bool isWon = true;
int c = 0;
int r = 0;
while (r < height)
{
while (c < width)
{
CellValue value = getCellVal(c, r);
if ((value == FLAG) ||
(value == MINE) ||
(value == COVERED_CELL) ||
(value == UNCOVERED_MINE))
{
isWon = false;
}
c++;
}
c = 0;
r++;
}
return isWon;
}
};
#endif
Board.h
#include <iostream>
#include <string>
#include "Cell.h"
#ifndef BOARD_H
#define BOARD_H
class Cell;
enum CellValue;
class Board
{
private:
int width;
int height;
int mines;
Cell*** cells;
public:
Board(int cols, int rows, int numMines);
int getWidth();
int getHeight();
int getMines();
CellValue* getCellVal(int x, int y);
void setCell(int x, int y, CellValue value);
void uncoverCell(int x, int y);
void flagCell(int x, int y);
bool isGameLost();
bool isGameWon();
};
#endif
I know this is a common error that people have and that there's more than a handful of questions about this on StackOverflow, but at this point, I've not found any that seem to match what I have here. What is the issue here?
Upvotes: 2
Views: 1058
Reputation: 39013
Seems like you're mixing header and source files. Your cpp file contains a class
declaration with all the functions defined inside. This is not what a cpp file looks like. It should only contain function declarations:
Board::Board(...)
{
...
}
bool Board::IsGameWon...
etc...
Upvotes: 4