Ejemplo n.º 1
0
static void
parse_root(Log4gConfigurator *base, xmlNodePtr node)
{
	Log4gLogger *logger = log4g_log_manager_get_root_logger();
	if (!logger) {
		return;
	}
	node = node->xmlChildrenNode;
	while (node) {
		if (!xmlStrcmp(node->name, (const xmlChar *)"property")) {
			parse_property(base, node, logger);
		} else if (!xmlStrcmp(node->name, (const xmlChar *)"level")) {
			parse_level(base, node, logger);
		} else if (!xmlStrcmp(node->name, (const xmlChar *)"appender")) {
			Log4gAppender *appender = parse_appender(base, node);
			if (appender) {
				log4g_logger_add_appender(logger, appender);
				g_object_unref(appender);
			}
		} else if (!xmlStrcmp(node->name, (const xmlChar *)"text")) {
			log4g_log_warn(Q_("invalid text element"));
		} else if (!xmlStrcmp(node->name, (const xmlChar *)"comment")) {
			/* do nothing */
		} else {
			log4g_log_warn(Q_("%s: invalid element"), node->name);
		}
		node = node->next;
	}
}
Ejemplo n.º 2
0
static void
parse_logger(Log4gConfigurator *base, xmlNodePtr node)
{
	xmlChar *name = xmlGetProp(node, (const xmlChar *)"name");
	if (!name) {
		log4g_log_error(Q_("loggers require a `name'"));
		goto exit;
	}
	Log4gLogger *logger = log4g_log_manager_get_logger((const gchar *)name);
	if (!logger) {
		goto exit;
	}
	xmlChar *additivity = xmlGetProp(node, (const xmlChar *)"additivity");
	if (additivity) {
		if (!xmlStrcmp(additivity, (const xmlChar *)"true")) {
			log4g_logger_set_additivity(logger, TRUE);
		} else if (!xmlStrcmp(additivity , (const xmlChar *)"false")) {
			log4g_logger_set_additivity(logger, FALSE);
		} else {
			log4g_log_error(Q_("%s: `additivity' must be "
						"a boolean value"), additivity);
		}
		xmlFree(additivity);
	} else {
		log4g_logger_set_additivity(logger, TRUE);
	}
	node = node->xmlChildrenNode;
	while (node) {
		if (!xmlStrcmp(node->name, (const xmlChar *)"level")) {
			parse_level(base, node, logger);
		} else if (!xmlStrcmp(node->name, (const xmlChar *)"appender")) {
			Log4gAppender *appender = parse_appender(base, node);
			if (appender) {
				log4g_logger_add_appender(logger, appender);
				g_object_unref(appender);
			}
		} else if (!xmlStrcmp(node->name, (const xmlChar *)"text")) {
			log4g_log_warn(Q_("invalid text element"));
		} else if (!xmlStrcmp(node->name, (const xmlChar *)"comment")) {
			/* do nothing */
		} else {
			log4g_log_warn(Q_("%s: invalid element"), node->name);
		}
		node = node->next;
	}
exit:
	if (name) {
		xmlFree(name);
	}
}
Ejemplo n.º 3
0
void			load_levels(t_level *levels[])
{
	int		fd[N_LEVELS];
	int		i;
	char	*path;
	char	*level_index;

	i = 0;
	if (N_LEVELS == 0)
		handle_errors(__func__, "N_LEVELS is null!", TRUE);
	while (i < N_LEVELS)
	{
		level_index = ft_itoa(i);
		path = ft_strjoin(LEVEL_PATH, level_index);
		ft_printf("loading %s ..\n", path);
		if ((fd[i] = open(path, O_RDONLY)) == -1)
			handle_errors(__func__, "level not found!", TRUE);
		levels[i] = init_level();
		parse_level(fd[i], levels[i]);
		ft_strdel(&path);
		ft_strdel(&level_index);
		i++;
	}
}
int sokoban_game::start_game()
{
    int iScore = 0;
    int iMoves = 0;
    iTotalMoves = 0;

    int iDirY, iDirX;

    const int iOffsetX = (TERMX > FULL_SCREEN_WIDTH) ? (TERMX - FULL_SCREEN_WIDTH) / 2 : 0;
    const int iOffsetY = (TERMY > FULL_SCREEN_HEIGHT) ? (TERMY - FULL_SCREEN_HEIGHT) / 2 : 0;

    parse_level();

    WINDOW *w_sokoban = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iOffsetY, iOffsetX);
    draw_border(w_sokoban);
    center_print(w_sokoban, 0, hilite(c_white), _("Sokoban"));

    std::vector<std::string> shortcuts;
    shortcuts.push_back(_("<+> next"));    // '+': next
    shortcuts.push_back(_("<-> prev"));    // '-': prev
    shortcuts.push_back(_("<r>eset"));     // 'r': reset
    shortcuts.push_back(_("<q>uit"));      // 'q': quit
    shortcuts.push_back(_("<u>ndo move")); // 'u': undo move

    int indent = 10;
    for (size_t i = 0; i < shortcuts.size(); i++) {
        indent = std::max(indent, utf8_width(shortcuts[i].c_str()) + 1);
    }
    indent = std::min(indent, 30);

    for (size_t i = 0; i < shortcuts.size(); i++) {
        shortcut_print(w_sokoban, i + 1, FULL_SCREEN_WIDTH - indent,
                       c_white, c_ltgreen, shortcuts[i].c_str());
    }

    int input = '.';

    int iPlayerY = 0;
    int iPlayerX = 0;

    bool bNewLevel = true;
    bool bMoved = false;
    do {
        if (bNewLevel) {
            bNewLevel = false;

            iMoves = 0;
            vUndo.clear();

            iPlayerY = mLevelInfo[iCurrentLevel]["PlayerY"];
            iPlayerX = mLevelInfo[iCurrentLevel]["PlayerX"];
            mLevel = vLevel[iCurrentLevel];
        }

        print_score(w_sokoban, iScore, iMoves);

        if (check_win()) {
            //we won yay
            if (!mAlreadyWon[iCurrentLevel]) {
                iScore += 500;
                mAlreadyWon[iCurrentLevel] = true;
            }
            input = '+';

        } else {
            draw_level(w_sokoban);
            wrefresh(w_sokoban);

            //Check input
            input = getch();
        }

        bMoved = false;
        switch (input) {
        case KEY_UP: /* up */
            iDirY = -1;
            iDirX = 0;
            bMoved = true;
            break;
        case KEY_DOWN: /* down */
            iDirY = 1;
            iDirX = 0;
            bMoved = true;
            break;
        case KEY_LEFT: /* left */
            iDirY = 0;
            iDirX = -1;
            bMoved = true;
            break;
        case KEY_RIGHT: /* right */
            iDirY = 0;
            iDirX = 1;
            bMoved = true;
            break;
        case 'q':
            return iScore;
            break;
        case 'u': {
            int iPlayerYNew = 0;
            int iPlayerXNew = 0;
            bool bUndoSkip = false;
            //undo move
            if (vUndo.size() > 0) {
                //reset last player pos
                mLevel[iPlayerY][iPlayerX] = (mLevel[iPlayerY][iPlayerX] == "+") ? "." : " ";
                iPlayerYNew = vUndo[vUndo.size() - 1].iOldY;
                iPlayerXNew = vUndo[vUndo.size() - 1].iOldX;
                mLevel[iPlayerYNew][iPlayerXNew] = vUndo[vUndo.size() - 1].sTileOld;

                vUndo.pop_back();

                bUndoSkip = true;
            }

            if (bUndoSkip && vUndo.size() > 0) {
                iDirY = vUndo[vUndo.size() - 1].iOldY;
                iDirX = vUndo[vUndo.size() - 1].iOldX;

                if (vUndo[vUndo.size() - 1].sTileOld == "$" ||
                    vUndo[vUndo.size() - 1].sTileOld == "*") {
                    mLevel[iPlayerY][iPlayerX] = (mLevel[iPlayerY][iPlayerX] == ".") ? "*" : "$";
                    mLevel[iPlayerY + iDirY][iPlayerX + iDirX] = (mLevel[iPlayerY + iDirY][iPlayerX + iDirX] == "*") ? "." : " ";

                    vUndo.pop_back();
                }
            }

            if (bUndoSkip) {
                iPlayerY = iPlayerYNew;
                iPlayerX = iPlayerXNew;
            }
        }
        break;
        case 'r':
            //reset level
            bNewLevel = true;
            break;
        case '+':
            //next level
            clear_level(w_sokoban);
            iCurrentLevel++;
            if (iCurrentLevel >= iNumLevel) {
                iCurrentLevel = 0;
            }
            bNewLevel = true;
            break;
        case '-':
            //prev level
            clear_level(w_sokoban);
            iCurrentLevel--;
            if (iCurrentLevel < 0) {
                iCurrentLevel =  iNumLevel - 1;
            }
            bNewLevel = true;
            break;
        default:
            break;
        }

        if (bMoved) {
            //check if we can move the player
            std::string sMoveTo = mLevel[iPlayerY + iDirY][iPlayerX + iDirX];
            bool bMovePlayer = false;

            if (sMoveTo != "#") {
                if (sMoveTo == "$" || sMoveTo == "*") {
                    //Check if we can move the package
                    std::string sMovePackTo = mLevel[iPlayerY + (iDirY * 2)][iPlayerX + (iDirX * 2)];
                    if (sMovePackTo == "." || sMovePackTo == " ") {
                        //move both
                        bMovePlayer = true;
                        mLevel[iPlayerY + (iDirY * 2)][iPlayerX + (iDirX * 2)] = (sMovePackTo == ".") ? "*" : "$";

                        vUndo.push_back(cUndo(iDirY, iDirX, sMoveTo));

                        iMoves--;
                    }
                } else {
                    bMovePlayer = true;
                }

                if (bMovePlayer) {
                    //move player
                    vUndo.push_back(cUndo(iPlayerY, iPlayerX, mLevel[iPlayerY][iPlayerX]));

                    mLevel[iPlayerY][iPlayerX] = (mLevel[iPlayerY][iPlayerX] == "+") ? "." : " ";
                    mLevel[iPlayerY + iDirY][iPlayerX + iDirX] = (sMoveTo == "." || sMoveTo == "*") ? "+" : "@";

                    iPlayerY += iDirY;
                    iPlayerX += iDirX;

                    iMoves++;
                    iTotalMoves++;
                }
            }
        }

    } while (true);

    return iScore;
}
int sokoban_game::start_game()
{
    int iScore = 0;
    int iMoves = 0;
    iTotalMoves = 0;

    int iDirY, iDirX;

    const int iOffsetX = (TERMX > FULL_SCREEN_WIDTH) ? (TERMX - FULL_SCREEN_WIDTH) / 2 : 0;
    const int iOffsetY = (TERMY > FULL_SCREEN_HEIGHT) ? (TERMY - FULL_SCREEN_HEIGHT) / 2 : 0;

    parse_level();

    WINDOW *w_sokoban = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iOffsetY, iOffsetX);
    draw_border(w_sokoban);
    center_print(w_sokoban, 0, hilite(c_white), _("Sokoban"));

    input_context ctxt("SOKOBAN");
    ctxt.register_cardinal();
    ctxt.register_action("NEXT");
    ctxt.register_action("PREV");
    ctxt.register_action("RESET");
    ctxt.register_action("QUIT");
    ctxt.register_action("UNDO");
    ctxt.register_action("HELP_KEYBINDINGS");

    std::vector<std::string> shortcuts;
    shortcuts.push_back(_("<+> next"));    // '+': next
    shortcuts.push_back(_("<-> prev"));    // '-': prev
    shortcuts.push_back(_("<r>eset"));     // 'r': reset
    shortcuts.push_back(_("<q>uit"));      // 'q': quit
    shortcuts.push_back(_("<u>ndo move")); // 'u': undo move

    int indent = 10;
    for (size_t i = 0; i < shortcuts.size(); i++) {
        indent = std::max(indent, utf8_width(shortcuts[i].c_str()) + 1);
    }
    indent = std::min(indent, 30);

    for (size_t i = 0; i < shortcuts.size(); i++) {
        shortcut_print(w_sokoban, i + 1, FULL_SCREEN_WIDTH - indent,
                       c_white, c_ltgreen, shortcuts[i]);
    }

    int iPlayerY = 0;
    int iPlayerX = 0;

    bool bNewLevel = true;
    bool bMoved = false;
    do {
        if (bNewLevel) {
            bNewLevel = false;

            iMoves = 0;
            vUndo.clear();

            iPlayerY = mLevelInfo[iCurrentLevel]["PlayerY"];
            iPlayerX = mLevelInfo[iCurrentLevel]["PlayerX"];
            mLevel = vLevel[iCurrentLevel];
        }

        print_score(w_sokoban, iScore, iMoves);

        std::string action;
        if (check_win()) {
            //we won yay
            if (!mAlreadyWon[iCurrentLevel]) {
                iScore += 500;
                mAlreadyWon[iCurrentLevel] = true;
            }
            action = "NEXT";

        } else {
            draw_level(w_sokoban);
            wrefresh(w_sokoban);

            //Check input
            action = ctxt.handle_input();
        }

        bMoved = false;
        if (ctxt.get_direction(iDirX, iDirY, action)) {
            bMoved = true;
        } else if (action == "QUIT") {
            return iScore;
        } else if (action == "UNDO") {
            int iPlayerYNew = 0;
            int iPlayerXNew = 0;
            bool bUndoSkip = false;
            //undo move
            if (!vUndo.empty()) {
                //reset last player pos
                mLevel[iPlayerY][iPlayerX] = (mLevel[iPlayerY][iPlayerX] == "+") ? "." : " ";
                iPlayerYNew = vUndo[vUndo.size() - 1].iOldY;
                iPlayerXNew = vUndo[vUndo.size() - 1].iOldX;
                mLevel[iPlayerYNew][iPlayerXNew] = vUndo[vUndo.size() - 1].sTileOld;

                vUndo.pop_back();

                bUndoSkip = true;
            }

            if (bUndoSkip && !vUndo.empty()) {
                iDirY = vUndo[vUndo.size() - 1].iOldY;
                iDirX = vUndo[vUndo.size() - 1].iOldX;

                if (vUndo[vUndo.size() - 1].sTileOld == "$" ||
                    vUndo[vUndo.size() - 1].sTileOld == "*") {
                    mLevel[iPlayerY][iPlayerX] = (mLevel[iPlayerY][iPlayerX] == ".") ? "*" : "$";
                    mLevel[iPlayerY + iDirY][iPlayerX + iDirX] = (mLevel[iPlayerY + iDirY][iPlayerX + iDirX] == "*") ?
                            "." : " ";

                    vUndo.pop_back();
                }
            }

            if (bUndoSkip) {
                iPlayerY = iPlayerYNew;
                iPlayerX = iPlayerXNew;
            }
        } else if (action == "RESET") {
            //reset level
            bNewLevel = true;
        } else if (action == "NEXT") {
            //next level
            clear_level(w_sokoban);
            iCurrentLevel++;
            if (iCurrentLevel >= iNumLevel) {
                iCurrentLevel = 0;
            }
            bNewLevel = true;
        } else if (action == "PREV") {
            //prev level
            clear_level(w_sokoban);
            iCurrentLevel--;
            if (iCurrentLevel < 0) {
                iCurrentLevel =  iNumLevel - 1;
            }
            bNewLevel = true;
        }

        if (bMoved) {
            //check if we can move the player
            std::string sMoveTo = mLevel[iPlayerY + iDirY][iPlayerX + iDirX];
            bool bMovePlayer = false;

            if (sMoveTo != "#") {
                if (sMoveTo == "$" || sMoveTo == "*") {
                    //Check if we can move the package
                    std::string sMovePackTo = mLevel[iPlayerY + (iDirY * 2)][iPlayerX + (iDirX * 2)];
                    if (sMovePackTo == "." || sMovePackTo == " ") {
                        //move both
                        bMovePlayer = true;
                        mLevel[iPlayerY + (iDirY * 2)][iPlayerX + (iDirX * 2)] = (sMovePackTo == ".") ? "*" : "$";

                        vUndo.push_back(cUndo(iDirY, iDirX, sMoveTo));

                        iMoves--;
                    }
                } else {
                    bMovePlayer = true;
                }

                if (bMovePlayer) {
                    //move player
                    vUndo.push_back(cUndo(iPlayerY, iPlayerX, mLevel[iPlayerY][iPlayerX]));

                    mLevel[iPlayerY][iPlayerX] = (mLevel[iPlayerY][iPlayerX] == "+") ? "." : " ";
                    mLevel[iPlayerY + iDirY][iPlayerX + iDirX] = (sMoveTo == "." || sMoveTo == "*") ? "+" : "@";

                    iPlayerY += iDirY;
                    iPlayerX += iDirX;

                    iMoves++;
                    iTotalMoves++;
                }
            }
        }

    } while (true);

    return iScore;
}
Ejemplo n.º 6
0
/* Function which parses command options; returns true if it
   ate an option */
static int
parse(int c, char **argv, int invert, unsigned int *flags,
      const struct ip6t_entry *entry,
      struct ip6t_entry_target **target)
{
	struct ip6t_log_info *loginfo = (struct ip6t_log_info *)(*target)->data;

	switch (c) {
	case '!':
		if (*flags & IP6T_LOG_OPT_LEVEL)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --log-level twice");

		if (check_inverse(optarg, &invert, NULL, 0))
			exit_error(PARAMETER_PROBLEM,
				   "Unexpected `!' after --log-level");

		loginfo->level = parse_level(optarg);
		*flags |= IP6T_LOG_OPT_LEVEL;
		break;

	case '#':
		if (*flags & IP6T_LOG_OPT_PREFIX)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --log-prefix twice");

		if (check_inverse(optarg, &invert, NULL, 0))
			exit_error(PARAMETER_PROBLEM,
				   "Unexpected `!' after --log-prefix");

		if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
			exit_error(PARAMETER_PROBLEM,
				   "Maximum prefix length %u for --log-prefix",
				   sizeof(loginfo->prefix) - 1);

		strcpy(loginfo->prefix, optarg);
		*flags |= IP6T_LOG_OPT_PREFIX;
		break;

	case '1':
		if (*flags & IP6T_LOG_OPT_TCPSEQ)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --log-tcp-sequence "
				   "twice");

		loginfo->logflags |= IP6T_LOG_TCPSEQ;
		*flags |= IP6T_LOG_OPT_TCPSEQ;
		break;

	case '2':
		if (*flags & IP6T_LOG_OPT_TCPOPT)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --log-tcp-options twice");

		loginfo->logflags |= IP6T_LOG_TCPOPT;
		*flags |= IP6T_LOG_OPT_TCPOPT;
		break;

	case '3':
		if (*flags & IP6T_LOG_OPT_IPOPT)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --log-ip-options twice");

		loginfo->logflags |= IP6T_LOG_IPOPT;
		*flags |= IP6T_LOG_OPT_IPOPT;
		break;

	default:
		return 0;
	}

	return 1;
}
Ejemplo n.º 7
0
static DFBBoolean
parse_command_line( int argc, char *argv[] )
{
     int n;

     for (n = 1; n < argc; n++) {
          const char *arg = argv[n];

          if (strcmp (arg, "-h") == 0 || strcmp (arg, "--help") == 0) {
               print_usage (argv[0]);
               return DFB_FALSE;
          }

          if (strcmp (arg, "-v") == 0 || strcmp (arg, "--version") == 0) {
               fprintf (stderr, "dfbg version %s\n", DIRECTFB_VERSION);
               return DFB_FALSE;
          }

          if (strcmp (arg, "-l") == 0 || strcmp (arg, "--layer") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_layer( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-m") == 0 || strcmp (arg, "--mode") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_mode( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-f") == 0 || strcmp (arg, "--format") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_format( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-b") == 0 || strcmp (arg, "--buffer") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_buffermode( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-o") == 0 || strcmp (arg, "--opacity") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_opacity( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-L") == 0 || strcmp (arg, "--level") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_level( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-R") == 0 || strcmp (arg, "--rotate") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_rotation( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-t") == 0 || strcmp (arg, "--test-lock") == 0) {
               test_lock = DSLF_READ | DSLF_WRITE;

               continue;
          }

          if (strcmp (arg, "-tr") == 0 || strcmp (arg, "--test-lock-read") == 0) {
               test_lock = DSLF_READ;

               continue;
          }

          if (strcmp (arg, "-tw") == 0 || strcmp (arg, "--test-lock-write") == 0) {
               test_lock = DSLF_WRITE;

               continue;
          }

          print_usage (argv[0]);

          return DFB_FALSE;
     }

     return DFB_TRUE;
}
Ejemplo n.º 8
0
int sokoban_game::start_game()
{
    int iScore = 0;
    int iMoves = 0;
    iTotalMoves = 0;

    int iDirY, iDirX;

    const int iOffsetX = (TERMX > FULL_SCREEN_WIDTH) ? (TERMX-FULL_SCREEN_WIDTH)/2 : 0;
    const int iOffsetY = (TERMY > FULL_SCREEN_HEIGHT) ? (TERMY-FULL_SCREEN_HEIGHT)/2 : 0;

    WINDOW* w_sokoban = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iOffsetY, iOffsetX);
    wborder(w_sokoban, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX);

    parse_level();

    mvwprintz(w_sokoban, 0, (FULL_SCREEN_WIDTH/2)-5, hilite(c_white), "Sokoban");

    mvwprintz(w_sokoban, 1, FULL_SCREEN_WIDTH-10, c_ltgreen, "+");
    wprintz(w_sokoban, c_white, " next");

    mvwprintz(w_sokoban, 2, FULL_SCREEN_WIDTH-10, c_ltgreen, "-");
    wprintz(w_sokoban, c_white, " prev");

    mvwprintz(w_sokoban, 3, FULL_SCREEN_WIDTH-10, c_ltgreen,  "r");
    wprintz(w_sokoban, c_white, "eset");

    mvwprintz(w_sokoban, 4, FULL_SCREEN_WIDTH-10, c_ltgreen,  "q");
    wprintz(w_sokoban, c_white, "uit");

    mvwprintz(w_sokoban, 5, FULL_SCREEN_WIDTH-10, c_ltgreen,  "u");
    wprintz(w_sokoban, c_white, "ndo move");

    int input = '.';

    int iPlayerY = 0;
    int iPlayerX = 0;

    bool bNewLevel = true;
    bool bMoved = false;
    do {
        if (bNewLevel) {
            bNewLevel = false;

            iMoves = 0;
            vUndo.clear();

            iPlayerY = mLevelInfo[iCurrentLevel]["PlayerY"];
            iPlayerX = mLevelInfo[iCurrentLevel]["PlayerX"];
            mLevel = vLevel[iCurrentLevel];
        }

        print_score(w_sokoban, iScore, iMoves);

        if (check_win()) {
            //we won yay
            if (!mAlreadyWon[iCurrentLevel]) {
                iScore += 500;
                mAlreadyWon[iCurrentLevel] = true;
            }
            input = '+';

        } else {
            draw_level(w_sokoban);
            wrefresh(w_sokoban);

            //Check input
            input = getch();
        }

        bMoved = false;
        switch (input) {
            case KEY_UP: /* up */
                iDirY = -1;
                iDirX = 0;
                bMoved = true;
                break;
            case KEY_DOWN: /* down */
                iDirY = 1;
                iDirX = 0;
                bMoved = true;
                break;
            case KEY_LEFT: /* left */
                iDirY = 0;
                iDirX = -1;
                bMoved = true;
                break;
            case KEY_RIGHT: /* right */
                iDirY = 0;
                iDirX = 1;
                bMoved = true;
                break;
            case 'q':
                return iScore;
                break;
            case 'u':
                {
                    int iPlayerYNew = 0;
                    int iPlayerXNew = 0;
                    bool bUndoSkip = false;
                    //undo move
                    if (vUndo.size() > 0) {
                        //reset last player pos
                        mLevel[iPlayerY][iPlayerX] = (mLevel[iPlayerY][iPlayerX] == "+") ? "." : " ";
                        iPlayerYNew = vUndo[vUndo.size()-1].iOldY;
                        iPlayerXNew = vUndo[vUndo.size()-1].iOldX;
                        mLevel[iPlayerYNew][iPlayerXNew] = vUndo[vUndo.size()-1].sTileOld;

                        vUndo.pop_back();

                        bUndoSkip = true;
                    }

                    if (bUndoSkip && vUndo.size() > 0) {
                        iDirY = vUndo[vUndo.size()-1].iOldY;
                        iDirX = vUndo[vUndo.size()-1].iOldX;

                        if (vUndo[vUndo.size()-1].sTileOld == "$" || vUndo[vUndo.size()-1].sTileOld == "*") {
                            mLevel[iPlayerY][iPlayerX] = (mLevel[iPlayerY][iPlayerX] == ".") ? "*" : "$";
                            mLevel[iPlayerY + iDirY][iPlayerX + iDirX] = (mLevel[iPlayerY + iDirY][iPlayerX + iDirX] == "*") ? "." : " ";

                            vUndo.pop_back();
                        }
                    }

                    if (bUndoSkip) {
                        iPlayerY = iPlayerYNew;
                        iPlayerX = iPlayerXNew;
                    }
                }
                break;
            case 'r':
                //reset level
                bNewLevel = true;
                break;
            case '+':
                //next level
                clear_level(w_sokoban);
                iCurrentLevel++;
                if (iCurrentLevel >= iNumLevel) {
                    iCurrentLevel = 0;
                }
                bNewLevel = true;
                break;
            case '-':
                //prev level
                clear_level(w_sokoban);
                iCurrentLevel--;
                if (iCurrentLevel < 0) {
                    iCurrentLevel =  iNumLevel - 1;
                }
                bNewLevel = true;
                break;
            default:
                break;
        }

        if (bMoved) {
            //check if we can move the player
            std::string sMoveTo = mLevel[iPlayerY + iDirY][iPlayerX + iDirX];
            bool bMovePlayer = false;

            if (sMoveTo != "#") {
                if (sMoveTo == "$" || sMoveTo == "*") {
                    //Check if we can move the package
                    std::string sMovePackTo = mLevel[iPlayerY + (iDirY * 2)][iPlayerX + (iDirX * 2)];
                    if (sMovePackTo == "." || sMovePackTo == " ") {
                        //move both
                        bMovePlayer = true;
                        mLevel[iPlayerY + (iDirY * 2)][iPlayerX + (iDirX * 2)] = (sMovePackTo == ".") ? "*" : "$";

                        vUndo.push_back(cUndo(iDirY, iDirX, sMoveTo));

                        iMoves--;
                    }
                } else {
                    bMovePlayer = true;
                }

                if (bMovePlayer) {
                    //move player
                    vUndo.push_back(cUndo(iPlayerY, iPlayerX, mLevel[iPlayerY][iPlayerX]));

                    mLevel[iPlayerY][iPlayerX] = (mLevel[iPlayerY][iPlayerX] == "+") ? "." : " ";
                    mLevel[iPlayerY + iDirY][iPlayerX + iDirX] = (sMoveTo == "." || sMoveTo == "*") ? "+" : "@";

                    iPlayerY += iDirY;
                    iPlayerX += iDirX;

                    iMoves++;
                    iTotalMoves++;
                }
            }
        }

    } while (true);

    return iScore;
}