-1

我们为下一个项目提供了一个头文件和 cpp 文件,我们需要从中派生一个类。这两个文件应该“开箱即用”正常工作,但由于某种原因,我遇到了这些错误,点击这些错误并没有把我带到任何地方。我猜这是版本问题,因为大多数书籍程序的扩展名都是 .cxx,我们正在使用 .cpp,但我对编程很陌生,所以我不确定。此外,大多数其他程序的书籍在 VS 2012 中运行良好。如果有帮助,我正在 Windows 7 64 位上使用 Visual Studio 2012。

错误:

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

共产党:

#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);
}

}
4

2 回答 2

0

你没有int main()功能。每个程序都必须有这个。

http://en.wikipedia.org/wiki/Main_function

于 2013-06-08T22:39:08.957 回答
0

它们可以开箱即用地正确编译main,但如果没有函数,它们将无法链接或运行。

您需要将它们与您自己的源代码结合起来,我希望它至少包含一个main以某种方式使用这些类的函数。第一步,从以下开始:

int main(void) {
    return 0;
}

这不会做任何有用的事情,但它应该让你克服直接的链接错误。

于 2013-06-08T22:39:36.013 回答