2013-06-08 3 views
-1

Нам был предоставлен заголовок и файл cpp для нашего следующего проекта, из которого нам нужно получить класс. Эти два файла должны корректно работать «из коробки», но по какой-то причине я получаю эти ошибки, и щелчок по ошибкам нигде не принимает меня. Я предполагаю, что это проблема с версией, так как большинство программ книг имеют расширение .cxx, и мы работаем с .cpp, но я довольно новичок в программировании, поэтому я не знаю точно. Кроме того, большинство других программ отлично работали в VS 2012. Я использую Visual Studio 2012 на Windows 7 64bit, если это помогает.Программа должна запускаться ... фатальная ошибка LNK1120 и ошибка LNK2019

Ошибки:

1>MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup 
1>Projects\Project 5\Debug\Project 5.exe : fatal error LNK1120: 1 unresolved externals 

Вот код для заголовка и CPP нашего базового класса и спасибо за помощь, ребята:

Заголовок:

#ifndef MAIN_SAVITCH_GAME 
#define MAIN_SAVITCH_GAME 
#include <queue> // Provides queue<string> 
#include <string> // Provides string 

namespace main_savitch_14 
{ 
class game 
{ 
public: 
    // ENUM TYPE 
enum who { HUMAN, NEUTRAL, COMPUTER }; // Possible game outcomes 

// CONSTRUCTOR and DESTRUCTOR 
game() { move_number = 0; } 
virtual ~game() { } 

// PUBLIC MEMBER FUNCTIONS 
// The play function should not be overridden. It plays one game, 
// with the human player moving first and the computer second. 
// The computer uses an alpha-beta look ahead algorithm to select its 
// moves. The return value is the winner of the game (or NEUTRAL for 
// a tie). 
who play(); 

protected: 
// ******************************************************************* 
// OPTIONAL VIRTUAL FUNCTIONS (overriding these is optional) 
// ******************************************************************* 
virtual void display_message(const std::string& message) const; 
    virtual std::string get_user_move() const; 
virtual who last_mover() const 
    { return (move_number % 2 == 1 ? HUMAN : COMPUTER); } 
virtual int moves_completed() const { return move_number; } 
virtual who next_mover() const 
    { return (move_number % 2 == 0 ? HUMAN : COMPUTER); } 
virtual who opposite(who player) const 
    { return (player == HUMAN) ? COMPUTER : HUMAN; } 
    virtual who winning() const; 

// ******************************************************************* 
// VIRTUAL FUNCTIONS THAT MUST BE OVERRIDDEND: 
// The overriding function should call the original when it finishes. 
// ******************************************************************* 
// Have the next player make a specified move: 
    virtual void make_move(const std::string& move) { ++move_number; } 
    // Restart the game from the beginning: 
    virtual void restart() { move_number = 0; } 

// ******************************************************************* 
    // PURE VIRTUAL FUNCTIONS 
// ******************************************************************* 
// (these must be provided for each derived class) 
    // Return a pointer to a copy of myself: 
    virtual game* clone() const = 0; 
    // Compute all the moves that the next player can make: 
    virtual void compute_moves(std::queue<std::string>& moves) const = 0; 
    // Display the status of the current game: 
    virtual void display_status() const = 0; 
    // Evaluate a board position: 
// NOTE: positive values are good for the computer. 
    virtual int evaluate() const = 0; 
    // Return true if the current game is finished: 
    virtual bool is_game_over() const = 0; 
    // Return true if the given move is legal for the next player: 
    virtual bool is_legal(const std::string& move) const = 0; 

private: 
    // MEMBER VARIABLES 
int move_number;      // Number of moves made so far 

// STATIC MEMBER CONSTANT 
static const int SEARCH_LEVELS = 4; // Levels for look-ahead evaluation 

    // PRIVATE FUNCTIONS (these are the same for every game) 
int eval_with_lookahead(int look_ahead, int beat_this); 
void make_computer_move(); 
void make_human_move(); 
}; 
} 

#endif 

CPP:

#include <cassert> // Provides assert 
#include <climits> // Provides INT_MAX and INT_MIN 
#include <iostream> // Provides cin, cout 
#include <queue>  // Provides queue<string> 
#include <string>  // Provides string 
#include "game.h"  // Provides definition of game class 
using namespace std; 

namespace main_savitch_14 
{ 
//************************************************************************* 
// STATIC MEMBER CONSTANTS 
const int game::SEARCH_LEVELS; 

//************************************************************************* 
// PUBLIC MEMBER FUNCTIONS 

game::who game::play() 
// The play function should not be overridden. It plays one round of the 
// game, with the human player moving first and the computer second. 
// The return value is the winner of the game (or NEUTRAL for a tie). 
{ 
restart(); 

while (!is_game_over()) 
{ 
    display_status(); 
    if (last_mover() == COMPUTER) 
    make_human_move(); 
    else 
    make_computer_move(); 
} 
display_status(); 
return winning(); 
} 



//************************************************************************* 
// OPTIONAL VIRTUAL FUNCTIONS (overriding these functions is optional) 

void game::display_message(const string& message) const 
{ 
cout << message; 
} 

string game::get_user_move() const 
{ 
string answer; 

display_message("Your move, please: "); 
getline(cin, answer); 
return answer; 
} 

game::who game::winning() const 
{ 
int value = evaluate(); // Evaluate based on move that was just made. 

if (value > 0) 
    return COMPUTER; 
else if (value < 0) 
    return HUMAN; 
else 
    return NEUTRAL; 
} 



//************************************************************************* 
// PRIVATE FUNCTIONS (these are the same for every game) 

int game::eval_with_lookahead(int look_ahead, int beat_this) 
// Evaluate a board position with lookahead. 
// --int look_aheads: How deep the lookahead should go to evaluate the move. 
// --int beat_this: Value of another move that we’re considering. If the 
// current board position can't beat this, then cut it short. 
// The return value is large if the position is good for the player who just 
// moved. 
{ 
    queue<string> moves; // All possible opponent moves 
int value;    // Value of a board position after opponent moves 
    int best_value;  // Evaluation of best opponent move 
    game* future;   // Pointer to a future version of this game 

    // Base case: 
if (look_ahead == 0 || is_game_over()) 
{ 
    if (last_mover() == COMPUTER) 
      return evaluate(); 
    else 
    return -evaluate(); 
} 

    // Recursive case: 
    // The level is above 0, so try all possible opponent moves. Keep the 
// value of the best of these moves from the opponent's perspective. 
    compute_moves(moves); 
assert(!moves.empty()); 
    best_value = INT_MIN; 
    while (!moves.empty()) 
    { 
    future = clone(); 
    future->make_move(moves.front()); 
    value = future->eval_with_lookahead(look_ahead-1, best_value); 
    delete future; 
    if (value > best_value) 
    { 
    if (-value <= beat_this) 
     return INT_MIN + 1; // Alpha-beta pruning 
    best_value = value; 
    } 
    moves.pop(); 
    } 

    // The value was calculated from the opponent's perspective. 
    // The answer we return should be from player's perspective, so multiply times -1: 
    return -best_value; 
} 

void game::make_computer_move() 
{ 
queue<string> moves; 
int value; 
int best_value; 
string best_move; 
game* future; 

// Compute all legal moves that the computer could make. 
compute_moves(moves); 
assert(!moves.empty()); 

// Evaluate each possible legal move, saving the index of the best 
// in best_index and saving its value in best_value. 
best_value = INT_MIN; 
while (!moves.empty()) 
{ 
    future = clone(); 
    future->make_move(moves.front()); 
    value = future->eval_with_lookahead(SEARCH_LEVELS, best_value); 
    delete future; 
    if (value >= best_value) 
    { 
    best_value = value; 
    best_move = moves.front(); 
    } 
    moves.pop(); 
} 

// Make the best move. 
make_move(best_move); 
} 

void game::make_human_move() 
{ 
    string move; 

move = get_user_move(); 
while (!is_legal(move)) 
{ 
    display_message("Illegal move.\n"); 
    move = get_user_move(); 
    } 
make_move(move); 
} 

} 

ответ

0

Они могут компилировать правильно из коробки, но без main функции, они не будут связывать или бежать.

Вам необходимо объединить их со своим исходным кодом, который я ожидаю содержать как минимум функцию main, которая каким-то образом использовала эти классы. В качестве первого шага, начните с:

int main(void) { 
    return 0; 
} 

Это не будет ничего полезного сделать, но он должен получить вас за немедленную ошибку связи.

+0

О, извиняюсь, у меня была реализация connect4 в начале с использованием game.cpp и .h, которые все еще вызывали аналогичные ошибки LNK. Я хотел упростить его, просто пытаясь скомпилировать файлы game.cpp и game.h в одиночку и не понимал об основных недостающих. Ошибка, которую я получаю с connect4, полученная из игры: 1> play_connect4.obj: ошибка LNK2019: неразрешенный внешний символ "public: __thiscall main_savitch_14 :: connect4 :: connect4 (void)" (?? 0connect4 @ main_savitch_14 @@ QAE @XZ), на которые ссылается функция _main – floatfil