/* puz_main.cc -- puz main function. Copyright (C) 2007 Casey Marshall */ #include #include #include #include #include "glr.h" #include "Lexer.h" #include "puz.h" #include "puzzle_state.h" int main(int argc, char **argv) { if (argc < 4) { std::cerr << argv[0] << ": expecting three arguments" << std::endl; std::cerr << "usage: " << argv[0] << " puzzle.dat outfile expression" << std::endl; exit(EXIT_FAILURE); } FILE *infile = fopen(argv[1], "r"); if (infile == NULL) { std::cerr << argv[0] << ": " << argv[1] << ": " << strerror(errno) << std::endl; exit(EXIT_FAILURE); } FILE *outfile = fopen(argv[2], "w"); if (outfile == NULL) { std::cerr << argv[0] << ": " << argv[2] << ": " << strerror(errno) << std::endl; exit(EXIT_FAILURE); } Lexer lex; std::string exprstr (argv[3]); Lexer::setInputString(exprstr); lex.nextToken(&lex); PuzContext context; GLR glr(&context, context.makeTables()); SemanticValue result; if (!glr.glrParse(lex, result)) { std::cerr << "parse error: " << exprstr << std::endl; exit(EXIT_FAILURE); } PuzContext::expression *expr = (PuzContext::expression *) result; state_map states; states.read_metadata(infile); states.read_nopointer_data(infile); fclose(infile); extern double edgeDistance; extern double manhattanDistance; extern double manhattanDistanceNoBlank; extern double neighborDistance; extern double neighborDistanceNoBlank; double epsilon = 1.0 / 10000.0; int hits = 0; for (state_map::iterator it = states.begin(); it != states.end(); it++) { puzzle_state state = (*it).first; double distance = (*it).second; edgeDistance = edge_distance(state); manhattanDistance = manhattan_distance(state, true); manhattanDistanceNoBlank = manhattan_distance(state, false); neighborDistance = neighbor_distance(state, true); neighborDistanceNoBlank = neighbor_distance(state, false); double value = expr->eval(); fprintf (outfile, "%f %f\n", distance, value); double delta = distance - value; if (delta < 0.0 && delta > -epsilon) hits++; else if (delta >= 0.0 && delta < epsilon) hits++; } std::cout << hits << " hits; accuracy: " << (((double) hits / (double) states.size()) * 100.0) << "%" << std::endl; fclose(outfile); exit(EXIT_SUCCESS); }