Ejemplo n.º 1
0
size_t DfpnSolver::MID(const DfpnBounds& maxBounds, DfpnHistory& history)
{
    maxBounds.CheckConsistency();
    SG_ASSERT(maxBounds.phi > 1);
    SG_ASSERT(maxBounds.delta > 1);

    ++m_numMIDcalls;
    size_t prevWork = 0;
    SgEmptyBlackWhite colorToMove = GetColorToMove();

    DfpnData data;
    if (TTRead(data)) 
    {
        prevWork = data.m_work;
        if (! maxBounds.GreaterThan(data.m_bounds))
            // Estimated bounds are larger than we had
            // anticipated. The calling state must have computed
            // the max bounds with out of date information, so just
            // return here without doing anything: the caller will
            // now update to this new info and carry on.
            return 0;
    }
    else
    {
        SgEmptyBlackWhite winner = SG_EMPTY;
        if (TerminalState(colorToMove, winner))
        {
            ++m_numTerminal;
            DfpnBounds terminal;
            if (colorToMove == winner)
                DfpnBounds::SetToWinning(terminal);
            else
            {
                SG_ASSERT(SgOppBW(colorToMove) == winner);
                DfpnBounds::SetToLosing(terminal);
            }
            TTWrite(DfpnData(terminal, SG_NULLMOVE, 1));
            return 1;
        }
    }
    
    ++m_generateMoves;
    DfpnChildren children;
    GenerateChildren(children.Children());

    // Not thread safe: perhaps move into while loop below later...
    std::vector<DfpnData> childrenData(children.Size());
    for (size_t i = 0; i < children.Size(); ++i)
        LookupData(childrenData[i], children, i);
    // Index used for progressive widening
    size_t maxChildIndex = ComputeMaxChildIndex(childrenData);

    SgHashCode currentHash = Hash();
    SgMove bestMove = SG_NULLMOVE;
    DfpnBounds currentBounds;
    size_t localWork = 1;
    do
    {
        UpdateBounds(currentBounds, childrenData, maxChildIndex);
        if (! maxBounds.GreaterThan(currentBounds))
            break;

        // Select most proving child
        std::size_t bestIndex = 999999;
        DfpnBoundType delta2 = DfpnBounds::INFTY;
        SelectChild(bestIndex, delta2, childrenData, maxChildIndex);
        bestMove = children.MoveAt(bestIndex);

        // Compute maximum bound for child
        const DfpnBounds childBounds(childrenData[bestIndex].m_bounds);
        DfpnBounds childMaxBounds;
        childMaxBounds.phi = maxBounds.delta 
            - (currentBounds.delta - childBounds.phi);
        childMaxBounds.delta = delta2 == DfpnBounds::INFTY ? maxBounds.phi :
            std::min(maxBounds.phi,
                     std::max(delta2 + 1, DfpnBoundType(delta2 * (1.0 + m_epsilon))));
        SG_ASSERT(childMaxBounds.GreaterThan(childBounds));
        if (delta2 != DfpnBounds::INFTY)
            m_deltaIncrease.Add(float(childMaxBounds.delta-childBounds.delta));

        // Recurse on best child
        PlayMove(bestMove);
        history.Push(bestMove, currentHash);
        localWork += MID(childMaxBounds, history);
        history.Pop();
        UndoMove();

        // Update bounds for best child
        LookupData(childrenData[bestIndex], children, bestIndex);

        // Compute some stats when find winning move
        if (childrenData[bestIndex].m_bounds.IsLosing())
        {
            m_moveOrderingIndex.Add(float(bestIndex));
            m_moveOrderingPercent.Add(float(bestIndex) 
                                      / (float)childrenData.size());
            m_totalWastedWork += prevWork + localWork
                - childrenData[bestIndex].m_work;
        }
        else if (childrenData[bestIndex].m_bounds.IsWinning())
            maxChildIndex = ComputeMaxChildIndex(childrenData);

    } while (! CheckAbort());

    // Find the most delaying move for losing states, and the smallest
    // winning move for winning states.
    if (currentBounds.IsSolved())
    {
        if (currentBounds.IsLosing())
        {
            std::size_t maxWork = 0;
            for (std::size_t i = 0; i < children.Size(); ++i)
            {
                if (childrenData[i].m_work > maxWork)
                {
                    maxWork = childrenData[i].m_work;
                    bestMove = children.MoveAt(i);
                }
            }
        }
        else
        {
            std::size_t minWork = DfpnBounds::INFTY;
            for (std::size_t i = 0; i < children.Size(); ++i)
            {
                if (childrenData[i].m_bounds.IsLosing() 
                    && childrenData[i].m_work < minWork)
                {
                    minWork = childrenData[i].m_work;
                    bestMove = children.MoveAt(i);
                }
            }
        }
    }
    
    // Store search results
    TTWrite(DfpnData(currentBounds, bestMove, localWork + prevWork));
    return localWork;
}
Ejemplo n.º 2
0
bool Library::process_phrase(const char *loc_str, read_line &io, bool force, bool json)
{
	if (NULL==loc_str)
		return true;

	std::string query;

	
	analyze_query(loc_str, query);
	if (!query.empty())
		io.add_to_history(query.c_str());
	


	gsize bytes_read;
	gsize bytes_written;
	GError *err=NULL;
	char *str=NULL;
	if (!utf8_input)
		str=g_locale_to_utf8(loc_str, -1, &bytes_read, &bytes_written, &err);
	else
		str=g_strdup(loc_str);

	if (NULL==str) {
		fprintf(stderr, _("Can not convert %s to utf8.\n"), loc_str);
		fprintf(stderr, "%s\n", err->message);
		g_error_free(err);
		return false;
	}

	if (str[0]=='\0')
		return true;

  
	TSearchResultList res_list;


	switch (analyze_query(str, query)) {
	case qtFUZZY:
		LookupWithFuzzy(query, res_list);
		break;
	case qtREGEXP:
		LookupWithRule(query, res_list);
		break;
	case qtSIMPLE:
		SimpleLookup(str, res_list);
		if (res_list.empty())
			LookupWithFuzzy(str, res_list);
		break;
	case qtDATA:
		LookupData(query, res_list);
		break;
	default:
		/*nothing*/;
	}

	if (!res_list.empty()) {    
		/* try to be more clever, if there are
		   one or zero results per dictionary show all
		*/
		bool show_all_results=true;
		typedef std::map< string, int, std::less<string> > DictResMap;
		if (!force) {
			DictResMap res_per_dict;
			for(TSearchResultList::iterator ptr=res_list.begin(); ptr!=res_list.end(); ++ptr){
				std::pair<DictResMap::iterator, DictResMap::iterator> r = 
					res_per_dict.equal_range(ptr->bookname);
				DictResMap tmp(r.first, r.second);
				if (tmp.empty()) //there are no yet such bookname in map
					res_per_dict.insert(DictResMap::value_type(ptr->bookname, 1));
				else {
					++((tmp.begin())->second);
					if (tmp.begin()->second>1) {
						show_all_results=false;
						break;
					}
				}
			}
		}//if (!force)

		if (!show_all_results && !force) {
			printf(_("Found %d items, similar to %s.\n"), res_list.size(), 
			       utf8_output ? str : utf8_to_locale_ign_err(str).c_str());
			for (size_t i=0; i<res_list.size(); ++i) {
				string loc_bookname, loc_def;
				loc_bookname=utf8_to_locale_ign_err(res_list[i].bookname);
				loc_def=utf8_to_locale_ign_err(res_list[i].def);
				printf("%d)%s-->%s\n", i,
				       utf8_output ?  res_list[i].bookname.c_str() : loc_bookname.c_str(),
				       utf8_output ? res_list[i].def.c_str() : loc_def.c_str());
			}
			int choise;
			for (;;) {
				string str_choise;
				printf(_("Your choice[-1 to abort]: "));
				
				if(!stdio_getline(stdin, str_choise)){
					putchar('\n');
					exit(EXIT_SUCCESS);
				}
				sscanf(str_choise.c_str(), "%d", &choise);
				if (choise>=0 && choise<int(res_list.size())) { 
					sdcv_pager pager;
					print_search_result(pager.get_stream(), res_list[choise]);
					break;
				} else if (choise==-1)
					break;
				else
					printf(_("Invalid choise.\nIt must be from 0 to %d or -1.\n"), 
					       res_list.size()-1);	  
			}		
		} else {
			sdcv_pager pager(force);
			if (!json) {
				fprintf(pager.get_stream(), _("Found %d items, similar to %s.\n"),
					res_list.size(), utf8_output ? str : utf8_to_locale_ign_err(str).c_str());
				for (PSearchResult ptr=res_list.begin(); ptr!=res_list.end(); ++ptr)
					print_search_result(pager.get_stream(), *ptr);
			} else {
				char *out;
				cJSON *root,*fld;
				root=cJSON_CreateArray();
				for (PSearchResult ptr=res_list.begin(); ptr!=res_list.end(); ++ptr) {
					const TSearchResult & res = *ptr;
					string loc_bookname, loc_def, loc_exp;
					if(!utf8_output){
						loc_bookname=utf8_to_locale_ign_err(res.bookname);
						loc_def=utf8_to_locale_ign_err(res.def);
						loc_exp=utf8_to_locale_ign_err(res.exp);
					}
					cJSON_AddItemToArray(root,fld=cJSON_CreateObject());
					cJSON_AddStringToObject(fld, "dict", utf8_output ? res.bookname.c_str() : loc_bookname.c_str());
					cJSON_AddStringToObject(fld, "word", utf8_output ? res.def.c_str() : loc_def.c_str());
					cJSON_AddStringToObject(fld, "definition", utf8_output ? res.exp.c_str() : loc_exp.c_str());
				}
				out=cJSON_Print(root);
				cJSON_Delete(root);
				fprintf(pager.get_stream(), "%s", out);
				free(out);
			}
		}
    
	} else {
		string loc_str;
		if (!utf8_output)
			loc_str=utf8_to_locale_ign_err(str);
    
		printf(_("Nothing similar to %s, sorry :(\n"), utf8_output ? str : loc_str.c_str());
	}
	g_free(str);

	return true;
}