Beispiel #1
0
void	xrSmoothNodes()
{
	Nodes	smoothed;	smoothed.reserve(g_nodes.size());
	Marks	mark;		mark.assign(g_nodes.size(),false);

	int inv_count = 0;
	for (u32 i=0; i<g_nodes.size(); i++)
	{
		vertex& N = g_nodes[i];

		Fvector	P1,P2,P3,P4,P,REF;
		int		c;

		// smooth point LF
		{
			bool	bCorner = false;

			c=1;	N.PointLF(REF);	P1.set(REF);
			if (N.nLeft()!=InvalidNode) {
				vertex& L = g_nodes[N.nLeft()];

				L.PointFR(P);	merge(P1);
				if (L.nForward()!=InvalidNode) {
					bCorner = true;
					vertex& C = g_nodes[L.nForward()];

					C.PointRB(P);	merge(P1);
				}
			}
			if (N.nForward()!=InvalidNode) {
				vertex& F = g_nodes[N.nForward()];

				F.PointBL(P);	merge(P1);
				if ((!bCorner) && (F.nLeft()!=InvalidNode)) {
					bCorner = true;

					vertex& C = g_nodes[F.nLeft()];
					C.PointRB(P);	merge(P1);
				}
			}
			R_ASSERT(c<=4);
			P1.div(float(c));
		}

		// smooth point FR
		{
			bool	bCorner = false;

			c=1;	N.PointFR(REF); P2.set(REF);
			if (N.nForward()!=InvalidNode) {
				vertex& F = g_nodes[N.nForward()];

				F.PointRB(P);	merge(P2);
				if (F.nRight()!=InvalidNode) {
					bCorner = true;
					vertex& C = g_nodes[F.nRight()];

					C.PointBL(P);	merge(P2);
				}
			}
			if (N.nRight()!=InvalidNode) {
				vertex& R = g_nodes[N.nRight()];

				R.PointLF(P);	merge(P2);
				if ((!bCorner) && (R.nForward()!=InvalidNode)) {
					bCorner = true;

					vertex& C = g_nodes[R.nForward()];
					C.PointBL(P);	merge(P2);
				}
			}
			R_ASSERT(c<=4);
			P2.div(float(c));
		}

		// smooth point RB
		{
			bool	bCorner = false;

			c=1;	N.PointRB(REF); P3.set(REF);
			if (N.nRight()!=InvalidNode) {
				vertex& R = g_nodes[N.nRight()];

				R.PointBL(P);	merge(P3);
				if (R.nBack()!=InvalidNode) {
					bCorner = true;
					vertex& C = g_nodes[R.nBack()];

					C.PointLF(P);	merge(P3);
				}
			}
			if (N.nBack()!=InvalidNode) {
				vertex& B = g_nodes[N.nBack()];

				B.PointFR(P);	merge(P3);
				if ((!bCorner) && (B.nRight()!=InvalidNode)) {
					bCorner = true;

					vertex& C = g_nodes[B.nRight()];
					C.PointLF(P);	merge(P3);
				}
			}
			R_ASSERT(c<=4);
			P3.div(float(c));
		}

		// smooth point BL
		{
			bool	bCorner = false;

			c=1;	N.PointBL(REF); P4.set(REF);
			if (N.nBack()!=InvalidNode) {
				vertex& B = g_nodes[N.nBack()];

				B.PointLF(P);	merge(P4);
				if (B.nLeft()!=InvalidNode) {
					bCorner = true;
					vertex& C = g_nodes[B.nLeft()];

					C.PointFR(P);	merge(P4);
				}
			}
			if (N.nLeft()!=InvalidNode) {
				vertex& L = g_nodes[N.nLeft()];

				L.PointRB(P);	merge(P4);
				if ((!bCorner) && (L.nBack()!=InvalidNode)) {
					bCorner = true;

					vertex& C = g_nodes[L.nBack()];
					C.PointFR(P);	merge(P4);
				}
			}
			R_ASSERT(c<=4);
			P4.div(float(c));
		}

		// align plane
		Fvector data[4]; data[0]=P1; data[1]=P2; data[2]=P3; data[3]=P4;
		Fvector vOffs,vNorm,D;
		vNorm.set(N.Plane.n);
		vOffs.set(N.Pos);
		Mgc::OrthogonalPlaneFit(
			4,(Mgc::Vector3*)data,
			*((Mgc::Vector3*)&vOffs),
			*((Mgc::Vector3*)&vNorm)
		);
		if (vNorm.y<0) vNorm.invert();

		// create _new node
		vertex NEW = N;
		NEW.Plane.build	(vOffs,vNorm);
		D.set			(0,1,0);
		N.Plane.intersectRayPoint(N.Pos,D,NEW.Pos);	// "project" position
		smoothed.push_back	(NEW);

		// verify placement
		/*
		mark[i]			= !!ValidNode	(NEW);

		if (!mark[i])	inv_count++;.
		*/
	}
	g_nodes = smoothed;

	if (inv_count) Msg("%d invalid nodes detected",inv_count);
}
Beispiel #2
0
int main(int argc, char **argv)
{
  char *file_input = NULL;
  int c;
  
  Node node;
  Nodes nodes;
  struct Summary summary;
  memset(&summary, 0, sizeof(struct Summary));
  
  // options
  while ((c = getopt(argc, argv, "i:")) != -1) {
    switch (c) {
      case 'i':
        file_input = optarg;
        break;
      default:
        break;
    }
  }
  
  if (!file_input) {
    printf("Usage: ./build_tree -i inputs.txt\n");
    exit(EXIT_SUCCESS);
  }
  
  // read input file
  std::ifstream fin(file_input);
  if (!fin.is_open()) {
    std::cerr << "open file failure: " << file_input << std::endl;
    exit(EXIT_FAILURE);
  }
  while (!fin.eof()) {
    std::string uid;
    std::string balance;
    if (!std::getline(fin, uid, '\t') || !std::getline(fin, balance, '\n')) {
      break;
    }
    make_user_node(uid.c_str(), atoll(balance.c_str()), &node);
    nodes.push_back(node);
    summary.sum += node.sum;
  }
  fin.close();
  summary.user_count = nodes.size();
  
  // nodes at level 0 should be sorted
  std::sort(nodes.begin(), nodes.end());
  
  int idx = 0;
  Nodes parents;
  parents.reserve(nodes.size()%2 + 1);
  while (nodes.size() > 1) {
    if (nodes.size() % 2 == 1) {
      summary.padding_sum += nodes[nodes.size()-1].sum;
      nodes.push_back(nodes[nodes.size()-1]);
    }
    
    for (Nodes::iterator it = nodes.begin(); it != nodes.end(); it++) {
      std::cout << idx++ << "\t" << summary.level << "\t" << it->sum << "\t";
      dump_hex(it->hash, 8);
      std::cout << std::endl;
    }
    parents.resize(0);
    build_parent_nodes(&nodes, &parents);
    nodes = parents;
    summary.level++;
  }
  std::cout << idx++ << "\t" << summary.level << "\t" << nodes[0].sum << "\t";
  dump_hex(nodes[0].hash, 8);
  std::cout << std::endl;
  
  std::cout << "summary:\t" << summary.user_count << "\t" << summary.sum << "\t"
    << summary.padding_sum << "\t" << summary.level << std::endl;
  
  return 0;
}
int UltimateTicTacToeMontecarloAI::realThink(const UltimateTicTacToeMontecarloAI::Board &board, const int previousMove, const int player) const
{
  //printBoard(board);
  if(maxIterations == 0) {
    Moves options = movementOptions(board, previousMove);
    return options.at(qrand() % options.size());
  }

  //qint64 now = QDateTime::currentMSecsSinceEpoch();
  //qDebug() << "c: " << c << ", maxIterations: " << maxIterations << ", maxChildren: " <<maxChildren;
  Nodes nodes;
  nodes.reserve(maxIterations * maxChildren);
  nodes.append(Node { 0, 1, board, previousMove, -1, Node::Children() });

  int i;
  for(i = 0; i < maxIterations; ++i)
  {
    int leafIndex = select(nodes);
    Node const& leaf = nodes.at(leafIndex);

    GameState leafState = gameState(leaf.board, player);
    if(leafState == GameState::WIN)
    {
/*      qDebug() << "---";
      printBoard(leaf.board);
*/
      break;
    }
    else if(leafState == GameState::LOSE)
    {
      backpropagate(leafIndex, nodes, -10);
    }
    else if(leafState == GameState::TIE)
    {
      backpropagate(leafIndex, nodes, -5);
    }
    else if(leafState == GameState::UNRESOLVED)
    {
      int nodeIndex = expand(leafIndex, nodes, player);

      Node const& node = nodes.at(nodeIndex);
      int score = simulate(node.board,  node.previousMove, player);

      backpropagate(nodeIndex, nodes, score);
    }
  }

  //qDebug() << "Found solution in " << i + 1 << " iterations";
  Node const& root = nodes.at(0);
  int bestChildIndex = pickBestChild(root, nodes, false);
  Node const& bestChild = nodes.at(bestChildIndex);

  //qDebug() << "AI took " << (QDateTime::currentMSecsSinceEpoch() - now) << " ms";

  /*for(int childIndex : root.children)
  {
    Node const& child = nodes.at(childIndex);
    qDebug() << child.previousMove << ":" << child.v << child.n;
  }*/
  //qDebug() << bestChild.previousMove / 9 << bestChild.previousMove %9;
  return bestChild.previousMove;
}