Ich kann den Standardkonstruktor nicht neu programmieren?



  • Hallo! Ich bin neu in C ++. Ich möchte ein Spiel erstellen, das in einem Binärbaum für das Blatt mit der höchsten Punktzahl aussieht. Zum Beispiel:

    ` 10

                 /    \
    
                6      14
    
               / \    /  \
    
              5   8  11  18`   
    

    Mein Problem ist, dass ich eine Klasse für Binärbäume habe, BTree, aber ich weiß nicht, wie man eine Brettklasse des Spiels mit der aktuellen Position baut. All mein Code, nicht funktional, ist auf GitHub zugänglich https://github.com/antoinecomp/NestedMonteCarloForBinaryTrees.

    Ich versuche eine Klasse zu programmieren. Allerdings habe ich Probleme beim Programmieren seines Herstellers. Tatsächlich dachte ich, wir könnten den Standardkonstruktor neu programmieren. Der leere Konstruktor, der nichts Besonderes tut. Ich habe ein Fehlerpaket und ich konzentriere mich auf das erste :

    g++ main2.cpp -o NestedMonteCarlo
    main2.cpp:118:15: error: ISO C++ forbids declaration of ‘board’ with no type [-fpermissive]
             board();
                   ^
    main2.cpp:119:15: error: expected class-name before ‘(’ token
             ~board();
                   ^
    main2.cpp:122:19: error: ISO C++ forbids declaration of ‘board’ with no type [-fpermissive]
       board(btree,node);
                       ^
    main2.cpp:125:14: error: ‘moves’ has not been declared
       legalMoves(moves)
                  ^
    main2.cpp:125:19: error: ISO C++ forbids declaration of ‘legalMoves’ with no type [-fpermissive]
       legalMoves(moves)
                       ^
    main2.cpp:125:19: error: expected ‘;’ at end of member declaration
    main2.cpp:132:3: error: ‘vector’ does not name a type
       vector<int> moves(2,NULL);
       ^
    main2.cpp:137:14: error: definition of implicitly-declared ‘Board::Board()’
     Board::Board(){
                  ^
    main2.cpp:143:15: error: definition of implicitly-declared ‘Board::~Board()’
     Board::~Board(){
                   ^
    main2.cpp:147:1: error: prototype for ‘Board::Board(btree, node)’ does not match any in class ‘Board’
     Board::Board(btree b, node n){
     ^
    main2.cpp:115:7: error: candidates are: Board::Board(const Board&)
     class Board{
           ^
    main2.cpp:115:7: error:                 Board::Board()
    main2.cpp:159:5: error: ‘board’ has not been declared
     int board::legalMoves(moves) 
         ^
    main2.cpp:159:23: error: ‘moves’ was not declared in this scope
     int board::legalMoves(moves) 
                           ^
    main2.cpp:160:1: error: expected ‘,’ or ‘;’ before ‘{’ token
     {
     ^
    

    Das erste ist main2.cpp:118:15: error: ISO C++ forbids declaration of ‘board’ with no type [-fpermissive]
    board();
    Aber Ich dachte, wir könnten den leeren Konstruktor umprogrammieren. Aber wann Ich schreibe int board(); der Fehler verschwindet. Aber es scheint mir dumm. Ein Konstruktor nimmt keinen Typ an.

    Ich legte schließlich alles in die gleiche Datei, weil das Modulieren des Codes ca mir mehr Fehler verursachte ...

    main2.cpp

    #define NULL 0
    //#include "nestedSimple.c"
    //#include "Board.h"
    
    // main2
    
    struct node
    {
      int key_value;
      node *left;
      node *right;
    };
    
    class btree
    {
        public:
            btree();
            ~btree();
    
            void insert(int key);
            node *search(int key);
            void destroy_tree();
    
        private:
            void destroy_tree(node *leaf);
            void insert(int key, node *leaf);
            node *search(int key, node *leaf);
    
            node *root;
    };
    
    btree::btree()
    {
      root=NULL;
    }
    
    btree::~btree()
    {
      destroy_tree();
    }
    
    void btree::destroy_tree(node *leaf)
    {
      if(leaf!=NULL)
      {
        destroy_tree(leaf->left);
        destroy_tree(leaf->right);
        delete leaf;
      }
    }
    
    void btree::insert(int key, node *leaf)
    {
      if(key< leaf->key_value)
      {
        if(leaf->left!=NULL)
         insert(key, leaf->left);
        else
        {
          leaf->left=new node;
          leaf->left->key_value=key;
          leaf->left->left=NULL;    //Sets the left child of the child node to null
          leaf->left->right=NULL;   //Sets the right child of the child node to null
        }  
      }
      else if(key>=leaf->key_value)
      {
        if(leaf->right!=NULL)
          insert(key, leaf->right);
        else
        {
          leaf->right=new node;
          leaf->right->key_value=key;
          leaf->right->left=NULL;  //Sets the left child of the child node to null
          leaf->right->right=NULL; //Sets the right child of the child node to null
        }
      }
    }
    void btree::insert(int key)
    {
      if(root!=NULL)
        insert(key, root);
      else
      {
        root=new node;
        root->key_value=key;
        root->left=NULL;
        root->right=NULL;
      }
    }
    node *btree::search(int key, node *leaf)
    {
      if(leaf!=NULL)
      {
        if(key==leaf->key_value)
          return leaf;
        if(key<leaf->key_value)
          return search(key, leaf->left);
        else
          return search(key, leaf->right);
      }
      else return NULL;
    }
    
    node *btree::search(int key)
    {
      return search(key, root);
    }
    
    void btree::destroy_tree()
    {
      destroy_tree(root);
    }
    
    class Board{
    
        public:
            board();
            ~board();
    
    		//a Board is made from a binary tree. Furthermore he has a score, a length
    		board(btree,node);
    
    		//And he has possible blows
    		legalMoves(moves)
    
        private:
    		//member variables
    		int length;
    		int score;
    		// create move ? Array of the following possibilities : left/right ? Or none if we reached the end
    		vector<int> moves(2,NULL);
    
    };
    
    Board::Board(){
    	newLength = 0;
    	newScore = 0;
    
    }; 
    
    Board::~Board(){
    
    }; 
    
    Board::Board(btree b, node n){
    	newLength = NULL; //TO-DO : number of nodes which have leaves BUT how to count them ?
    
    	newScore = n->key_value; //DONE? : number on the current node FROM node
    
    	if(n->*left != NULL)
    		moves[0] = n->*left;//DONE? array of the left and right positions from current state 	//node *left; and node *right;
    		moves[1] = n->*right;
    
    }; 
    
    // gives the number of leaves we can play : either 2 or 0 in the binary-tree case.
    int board::legalMoves(moves) 
    {
    	//If there is leaves there is at least two moves.
    	if(n->*left != NULL){
    		return 2;	
    	}//otherwise there is no possibilities
    	else{
    		return 0;
    	}
    
    };
    
    /**/
    
    double playout (Board * board) {
      Move listeCoups [MaxLegalMoves];
      while (true) {
        int nb = board->legalMoves (listeCoups);
        if ((nb == 0) || board->terminal ())
          return board->score ();
        int n = rand () % nb;
        board->play (listeCoups [n]);
        if (board->length >= MaxPlayoutLength - 20) {
          return 0;
        }
      }
    }
    
    #include <float.h>
    
    double bestScoreNested = -DBL_MAX;
    
    int lengthBestRollout [10];
    double scoreBestRollout [10];
    Move bestRollout [10] [MaxPlayoutLength];
    
    Board bestBoard;
    
    // What is int n ?
    double nested (Board & board, int n) {
      int nbMoves = 0;
      Move moves [MaxLegalMoves];
    
      lengthBestRollout [n] = -1;
      scoreBestRollout [n] = -DBL_MAX;
      float res;
      while (true) {
        if (board.terminal ())
          return 0.0;
          //return board.score ();
        nbMoves = board.legalMoves (moves);
        for (int i = 0; i < nbMoves; i++) {
          Board b = board;
          b.play (moves [i]);
    		//what is n ?
          if (n == 1)
    	playout (&b);
          else
    	nested (b, n - 1);     
          double score = b.score ();
          if (score > scoreBestRollout [n]) {
    	scoreBestRollout [n] = score;
    	lengthBestRollout [n] = b.length;
    	for (int k = 0; k < b.length; k++)
    	  bestRollout [n] [k] = b.rollout [k];
    	// what is n ?
    	if (n > 3) {
    	  for (int t = 0; t < n - 1; t++)
    	    fprintf (stderr, "\t");
    	  fprintf (stderr, "n = %d, progress = %d, score = %f\n", n, board.length, scoreBestRollout [n]);
              int depth = 0;
              b.print (stderr);
    	  fprintf (stderr, "\n");
    	}
    	if ((n > 1) && (score > bestScoreNested)) {
    	  bestScoreNested = score;
    	  fprintf (stderr, "best score = %f\n", score);
              b.print (stderr);
    	  fprintf (stderr, "\n");
              bestBoard = b;
            }
          }
        }
        board.play (bestRollout [n] [board.length]);
      }
      return 0.0;
    }
    
    /**/
    
    int main(int argc, char *argv []) {
        btree b;
        b.insert(5);
        b.insert(6);
        b.insert(8);
        b.insert(10);
        b.insert(11);
        b.insert(14);
        b.insert(18);
    
    	// create board with b 
    	board boa(b)
    
        nestedSimple(b, 3);
        bestBoard.print (stderr);
        fprintf (stderr, "best score %lf\n", bestBoard.score ());
    
    	return(0);
    }
    

  • Global Moderator |  Mod

    Die einzig interessante Stelle im Code hast du weggelassen. Die hier gezeigte Board.h ist ganz eindeutig nicht die, auf die sich die Fehlermeldungen beziehen.



  • @MikeC
    Du weisst Schon Dass bezeichner In c++ case Sensitive sind, Oder?



  • Deine Klasse heißt Board, dann kann der Konstruktor nicht board heißen.



  • manni66 schrieb:

    Deine Klasse heißt Board, dann kann der Konstruktor nicht board heißen.

    Ha, ja, danke ! Entschuldigung. Das ist ein sehr dummer Fehler.

    Ich habe alle meine Fehler geübt. Aber es gibt welche, die bleiben.

    Vor allem im Board mache ich eine legalMoves (Moves) -Funktion, die angibt, welche Bewegungen ich auf dem Board machen darf. Moves ist ein Array von zwei Moves, die ich machen oder null machen kann. das erkläre ich privat.

    Es scheint jedoch, dass es nicht die Art ist, es zu erklären :

    main2.cpp:126:14: error: ‘moves’ has not been declared
       legalMoves(moves); 
                  ^
    

    Die ganze Fehlermeldung ist:

    mike@mike-thinks:~/NestedMonteCarlo/NestedForBinaryTrees$ g++ main2.cpp -o NestedMonteCarlo
    main2.cpp:126:14: error: ‘moves’ has not been declared
       legalMoves(moves); // error: ‘moves’ has not been declared : Yes it has !
                  ^
    main2.cpp:126:19: error: ISO C++ forbids declaration of ‘legalMoves’ with no type [-fpermissive]
       legalMoves(moves); // error: ‘moves’ has not been declared : Yes it has !
                       ^
    main2.cpp:133:3: error: ‘vector’ does not name a type
       vector<*node> moves(2,NULL);
       ^
    main2.cpp: In constructor ‘Board::Board(btree, node)’:
    main2.cpp:153:9: error: ‘left’ was not declared in this scope
      if(n->*left != NULL)
             ^
    main2.cpp:154:3: error: ‘moves’ was not declared in this scope
       moves[0] = n->*left;//DONE? array of the left and right positions from curren
       ^
    main2.cpp:155:3: error: ‘moves’ was not declared in this scope
       moves[1] = n->*right;
       ^
    main2.cpp:155:18: error: ‘right’ was not declared in this scope
       moves[1] = n->*right;
                      ^
    main2.cpp: At global scope:
    main2.cpp:160:28: error: ‘int Board::legalMoves’ is not a static data member of ‘class Board’
     int Board::legalMoves(moves){
                                ^
    main2.cpp:160:23: error: ‘moves’ was not declared in this scope
     int Board::legalMoves(moves){
                           ^
    main2.cpp:160:29: error: expected ‘,’ or ‘;’ before ‘{’ token
     int Board::legalMoves(moves){
                                 ^
    

    Wie kann also eine öffentliche Funktion einer Klasse private Attribute als Argumente berücksichtigen?

    Ich habe den gesamten Code in eine Datei geschrieben: main2.cpp :

    #define NULL 0
    #include <vector>
    
    // main2
    
    struct node
    {
      int key_value;
      node *left;
      node *right;
    };
    
    class btree
    {
        public:
            btree();
            ~btree();
    
            void insert(int key);
            node *search(int key);
            void destroy_tree();
    
        private:
            void destroy_tree(node *leaf);
            void insert(int key, node *leaf);
            node *search(int key, node *leaf);
    
            node *root;
    };
    
    btree::btree()
    {
      root=NULL;
    }
    
    btree::~btree()
    {
      destroy_tree();
    }
    
    void btree::destroy_tree(node *leaf)
    {
      if(leaf!=NULL)
      {
        destroy_tree(leaf->left);
        destroy_tree(leaf->right);
        delete leaf;
      }
    }
    
    void btree::insert(int key, node *leaf)
    {
      if(key< leaf->key_value)
      {
        if(leaf->left!=NULL)
         insert(key, leaf->left);
        else
        {
          leaf->left=new node;
          leaf->left->key_value=key;
          leaf->left->left=NULL;    //Sets the left child of the child node to null
          leaf->left->right=NULL;   //Sets the right child of the child node to null
        }  
      }
      else if(key>=leaf->key_value)
      {
        if(leaf->right!=NULL)
          insert(key, leaf->right);
        else
        {
          leaf->right=new node;
          leaf->right->key_value=key;
          leaf->right->left=NULL;  //Sets the left child of the child node to null
          leaf->right->right=NULL; //Sets the right child of the child node to null
        }
      }
    }
    void btree::insert(int key)
    {
      if(root!=NULL)
        insert(key, root);
      else
      {
        root=new node;
        root->key_value=key;
        root->left=NULL;
        root->right=NULL;
      }
    }
    node *btree::search(int key, node *leaf)
    {
      if(leaf!=NULL)
      {
        if(key==leaf->key_value)
          return leaf;
        if(key<leaf->key_value)
          return search(key, leaf->left);
        else
          return search(key, leaf->right);
      }
      else return NULL;
    }
    
    node *btree::search(int key)
    {
      return search(key, root);
    }
    
    void btree::destroy_tree()
    {
      destroy_tree(root);
    }
    
    class Board{
    
        public:
            Board();
            ~Board();
    
    		//a Board is made from a binary tree. Furthermore he has a score, a length
    		Board(btree,node);
    
    		//And he has possible blows
    		legalMoves(moves); // error: ‘moves’ has not been declared : Yes it has ! Just below !
    
        private:
    		//member variables
    		int length;
    		int score;
    		// create move ? Array of the following possibilities : left/right ? Or none if we reached the end
    		vector<*node> moves(2,NULL);
    
    };
    
    Board::Board(){
    	length = 0;
    	score = 0;
    
    }; 
    
    Board::~Board(){
    
    }; 
    
    Board::Board(btree b, node n){
    	length = NULL; //TO-DO : number of nodes which have leaves BUT how to count them ?
    
    	score = n.key_value; //DONE? : number on the current node FROM node
    
    	if(n->*left != NULL)
    		moves[0] = n->*left;//DONE? array of the left and right positions from current state 	//node *left; and node *right;
    		moves[1] = n->*right;
    
    }; 
    
    // gives the number of leaves we can play : either 2 or 0 in the binary-tree case.
    int Board::legalMoves(moves){
    	//If there is leaves there is at least two moves.
    	if(n->*left != NULL){
    		return 2;	
    	}//otherwise there is no possibilities
    	else{
    		return 0;
    	}
    
    };
    
    /**/
    
    double playout (Board * board) {
      Move listeCoups [MaxLegalMoves];
      while (true) {
        int nb = board->legalMoves (listeCoups);
        if ((nb == 0) || board->terminal ())
          return board->score ();
        int n = rand () % nb;
        board->play (listeCoups [n]);
        if (board->length >= MaxPlayoutLength - 20) {
          return 0;
        }
      }
    };
    
    #include <float.h>
    
    double bestScoreNested = -DBL_MAX;
    
    int lengthBestRollout [10];
    double scoreBestRollout [10];
    Move bestRollout [10] [MaxPlayoutLength];
    
    Board bestBoard;
    
    // What is int n ?
    double nested (Board & board, int n) {
      int nbMoves = 0;
      Move moves [MaxLegalMoves];
    
      lengthBestRollout [n] = -1;
      scoreBestRollout [n] = -DBL_MAX;
      float res;
      while (true) {
        if (board.terminal ())
          return 0.0;
          //return board.score ();
        nbMoves = board.legalMoves (moves);
        for (int i = 0; i < nbMoves; i++) {
          Board b = board;
          b.play (moves [i]);
    		//what is n ?
          if (n == 1)
    	playout (&b);
          else
    	nested (b, n - 1);     
          double score = b.score ();
          if (score > scoreBestRollout [n]) {
    	scoreBestRollout [n] = score;
    	lengthBestRollout [n] = b.length;
    	for (int k = 0; k < b.length; k++)
    	  bestRollout [n] [k] = b.rollout [k];
    	// what is n ?
    	if (n > 3) {
    	  for (int t = 0; t < n - 1; t++)
    	    fprintf (stderr, "\t");
    	  fprintf (stderr, "n = %d, progress = %d, score = %f\n", n, board.length, scoreBestRollout [n]);
              int depth = 0;
              b.print (stderr);
    	  fprintf (stderr, "\n");
    	}
    	if ((n > 1) && (score > bestScoreNested)) {
    	  bestScoreNested = score;
    	  fprintf (stderr, "best score = %f\n", score);
              b.print (stderr);
    	  fprintf (stderr, "\n");
              bestBoard = b;
            }
          }
        }
        board.play (bestRollout [n] [board.length]);
      }
      return 0.0;
    };
    
    /**/
    
    int main(int argc, char *argv []) {
        btree b;
        b.insert(5);
        b.insert(6);
        b.insert(8);
        b.insert(10);
        b.insert(11);
        b.insert(14);
        b.insert(18);
    
    	// create board with b 
    	board boa(b)
    
        nestedSimple(b, 3);
        bestBoard.print (stderr);
        fprintf (stderr, "best score %lf\n", bestBoard.score ());
    
    	return(0);
    }
    

    Danke für deine Hilfe, du bist großartig!


  • Global Moderator |  Mod

    Was soll man sagen? Der Compiler hat recht. Du sagst, moves wäre deklariert. Aber wo? Zeile 131 ist keine Typendeklaration und sowieso auch erst nach Zeile 124. Meinst du vielleicht den Typen Move (es ist eine gute Idee, Typen immer mit Großbuchstaben beginnen zu lassen, dann sieht man sie besser)? Aber auch der ist an der Stelle nicht deklariert. Tatsächlich sehe ich nirgendwo, wo der Typ Move herkommt, den du später noch benutzt.