2010-10-17 22 views
4

我創建了下面的抽象類來評估簡單遊戲的棋盤位置。抽象類被每個派生類覆蓋,以便只有評估函數在game.h中定義。創建與矢量作爲關鍵和自定義類作爲值的地圖的問題

我想通過使用memoization使我的程序更高效,但我無法讓我的地圖正常工作。編譯器爲行結果[board] = best拋出一個錯誤。該行嘗試將映射到當前板的值(整數矢量)設置爲從該位置可能的最佳移動。移動是我創建的一個類,它只包含一個分數,一個要移除的數字以創建下一個棋盤,以及索引(樁)從中刪除數字。

'results [board] = best'的編譯器錯誤表示沒有匹配的函數調用來移動:: move()。我不明白這個錯誤,因爲我不想創建一個新的移動,只是存儲當前的最佳舉措。我曾嘗試創建一個臨時移動並存儲它,所以我知道這是不正確的。最後一點 - 代碼編譯和運行完全沒有那行代碼,所以我知道算法和所有的子類都能正常工作。任何幫助,將不勝感激!

// VIRTUAL FUNCS 
// All virtual functions must be overridden by subclasses 

virtual ~game(){ } 

// initialize 
virtual void initialize(int numPlayers, std::vector<int> board) = 0; 


// gameHasEnded 
virtual bool gameHasEnded(std::vector<int> board) const = 0; 

// display 
virtual void display(std::vector<int> board) const = 0; 

// makeNewBoard 
virtual std::vector<int> makeNewBoard(std::vector<int> currBoard, move m) = 0; 

// generateMoves 
virtual std::vector<move> generateMoves(std::vector<int> currBoard) = 0; 

// compare 
virtual move compare(std::vector<int> board1, std::vector<int> board2) = 0; 

// NON-VIRTUAL FUNCS 

// 
// Name:   evaluate 
// Description: Evaluates a given board position. Determines whether 
//     or not the current position is a winning position 
//     or a losing position. A winning position is 
//     designated by a 1, a losing by a -1. 
// Modifies:  The board and the score. 
// Returns:  The best possible move from this position. 
//     
move evaluate( std::vector<int> board, int multiplier = 1, int currScore = -100) { 

    // Base case is defined by subclasses 
    if(gameHasEnded(board)) { 
    move toReturn(multiplier, 0); 
    return toReturn; 
    } // end-if 

    // If game is not over 
    else { 

    std::map<std::vector<int>,move>::iterator iter = results.find(board); 
    if(iter != results.end()) { 
     return iter->second; 
    } 
    else { 

     move best(-2,0); // Just a place holder. Is overridden later. 
     int s = 0; // Stores the score 

     std::vector<move> nextMove; 
     // generate all possible boards from this position - defined by subclass 
     nextMove = generateMoves(board); 

     // For each board position 
     for(int i = 0; i < ((int)nextMove.size()); ++i) { 
     std::vector<int> newBoard; 

     // Create a new possible board state 
     newBoard = makeNewBoard(board, nextMove[i]); 

     move dif = compare(board, newBoard); // Get the move that was made 
     move m(0,0); // place holder 
     m = evaluate(newBoard, multiplier*-1, currScore); // recurse through all positions 
     s += m.getScore(); 
     // If this is the best score so far 
     if(m.getScore() > currScore) { 

      m.setNumTake(dif.getNumTake()); // get the move 
      m.setPile(dif.getPile()); 
      best = m; // store the move 
      currScore = m.getScore(); // update the score 

     } 

     } 
     best.setScore(s); 

     ////////////////////////////// THIS IS THE LINE THAT THROWS A COMPILER ERROR 

     results[ board ] = best; 

     ////////////////////////////////// 

     return best; // return best move 
    } 
    } 
    return move(2,2); // dummy return. should never happen 
    } 

私人://數據成員

std::map<std::vector<int>,move> results; 

};

+0

檢查http://stackoverflow.com/questions/695645/why-does-the-c-map-type-argument-require-an-empty-constructor-當使用 – a1ex07 2010-10-17 22:40:01

回答

2

如果使用operator [],則需要缺省構造函數。

如果地圖不包含密鑰board的元素,map的operator []構造一個新的默認對象並將其插入到地圖中。只有這樣才能完成best

3

的任務您可以使用默認構造函數創建任何用作具有[]運算符的映射中的值的類。

results[ board ] = best; 

將做以下

  1. 創建默認move()用鑰匙board
  2. 返回到該地址
  3. 參考覆蓋通過分配best它的默認行動。

你是失敗的步驟1.

+1

只有在使用operator []時,需要使用默認構造函數。您可以使用find和insert將一個類用作沒有默認構造函數的值。 – SebastianK 2010-10-17 22:38:33

+0

那麼我只需要定義一個默認的移動構造函數?這將允許創建一個臨時移動,然後最好將其存儲,這是正確的嗎? – Mike 2010-10-17 22:45:07

+0

@ SebastianK:謝謝,我更正了答案。 – Akusete 2010-10-17 22:45:50

相關問題