void POCMAN::GeneratePreferred(const STATE& state, const HISTORY& history, vector<int>& actions, const STATUS& status) const { const POCMAN_STATE& pocstate = safe_cast<const POCMAN_STATE&>(state); if (history.Size()) { int action = history.Back().Action; int observation = history.Back().Observation; // If power pill and can see a ghost then chase it if (pocstate.PowerSteps > 0 && (observation & 15 != 0)) { for (int a = 0; a < 4; ++a) if (CheckFlag(observation, a)) actions.push_back(a); } // Otherwise avoid observed ghosts and avoid changing directions else { for (int a = 0; a < 4; ++a) { COORD newpos = NextPos(pocstate.PocmanPos, a); if (newpos.Valid() && !CheckFlag(observation, a) && COORD::Opposite(a) != action) actions.push_back(a); } } } }
void QNODE::DisplayValue(HISTORY& history, int maxDepth, ostream& ostr, const double *qvalue) const { history.Display(ostr); if (qvalue) { ostr << "q=" << *qvalue; } ImmediateReward.Print(": r=", ostr); Observation.Print(", o=", ostr); ostr << std::endl; for (int observation = 0; observation < NumChildren; observation++) { if (Children[observation]) { std::stringstream ss; ss << "\t\t\t#" << observation; // Children[observation]->GetCumulativeReward().Print(ss.str().c_str(), ostr); } } if (history.Size() >= maxDepth) return; for (int observation = 0; observation < NumChildren; observation++) { if (Children[observation]) { history.Back().Observation = observation; Children[observation]->DisplayValue(history, maxDepth, ostr); } } }
// ---------------------------------------------------------------------------------------------- // following functions use function parameters to determine range of frames void EDITOR::toggleInput(int start, int end, int joy, int button, int consecutivenessTag) { if (joy < 0 || joy >= joysticksPerFrame[getInputType(currMovieData)]) return; int check_frame = end; if (start > end) { // swap int temp_start = start; start = end; end = temp_start; } if (start < 0) start = end; if (end >= currMovieData.getNumRecords()) return; if (currMovieData.records[check_frame].checkBit(joy, button)) { // clear range for (int i = start; i <= end; ++i) currMovieData.records[i].clearBit(joy, button); greenzone.invalidateAndUpdatePlayback(history.registerChanges(MODTYPE_UNSET, start, end, 0, NULL, consecutivenessTag)); } else { // set range for (int i = start; i <= end; ++i) currMovieData.records[i].setBit(joy, button); greenzone.invalidateAndUpdatePlayback(history.registerChanges(MODTYPE_SET, start, end, 0, NULL, consecutivenessTag)); } }
bool ROCKSAMPLE::LocalMove(STATE& state, const HISTORY& history, int stepObs, const STATUS& status) const { _unused(status); ROCKSAMPLE_STATE& rockstate = safe_cast<ROCKSAMPLE_STATE&>(state); int rock = Random(NumRocks); rockstate.Rocks[rock].Valuable = !rockstate.Rocks[rock].Valuable; if (history.Back().Action > E_SAMPLE) // check rock { rock = history.Back().Action - E_SAMPLE - 1; int realObs = history.Back().Observation; // Condition new state on real observation int newObs = GetObservation(rockstate, rock); if (newObs != realObs) return false; // Update counts to be consistent with real observation if (realObs == E_GOOD && stepObs == E_BAD) rockstate.Rocks[rock].Count += 2; if (realObs == E_BAD && stepObs == E_GOOD) rockstate.Rocks[rock].Count -= 2; } return true; }
// --------------------------------------------------------------------------------- LRESULT APIENTRY historyListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { extern HISTORY history; switch(msg) { case WM_CHAR: case WM_KEYDOWN: case WM_KEYUP: case WM_KILLFOCUS: return 0; case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: { if (GetFocus() != hWnd) SetFocus(hWnd); // perform hit test LVHITTESTINFO info; info.pt.x = GET_X_LPARAM(lParam); info.pt.y = GET_Y_LPARAM(lParam); ListView_SubItemHitTest(hWnd, (LPARAM)&info); history.handleSingleClick(info.iItem); return 0; } case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: { if (GetFocus() != hWnd) SetFocus(hWnd); playback.handleMiddleButtonClick(); return 0; } case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: if (GetFocus() != hWnd) SetFocus(hWnd); return 0; case WM_MOUSEWHEEL: { if (!history.isCursorOverHistoryList()) return SendMessage(pianoRoll.hwndList, msg, wParam, lParam); break; } case WM_MOUSEWHEEL_RESENT: { // this is message from Piano Roll // it means that cursor is currently over History List, and user scrolls the wheel (although focus may be on some other window) // ensure that wParam's low-order word is 0 (so fwKeys = 0) CallWindowProc(hwndHistoryList_oldWndProc, hWnd, WM_MOUSEWHEEL, wParam & ~(LOWORD(-1)), lParam); return 0; } case WM_MOUSEACTIVATE: if (GetFocus() != hWnd) SetFocus(hWnd); break; } return CallWindowProc(hwndHistoryList_oldWndProc, hWnd, msg, wParam, lParam); }
void VNODE::DisplayValue(HISTORY& history, int maxDepth, ostream& ostr) const { if (history.Size() >= (uint) maxDepth) return; for (int action = 0; action < NumChildren; action++) { history.Add(action,-1); Children[action].DisplayValue(history, maxDepth, ostr); history.Pop(); } }
// following functions use current Selection to determine range of frames bool EDITOR::handleColumnSet() { RowsSelection* current_selection = selection.getCopyOfCurrentRowsSelection(); if (current_selection->size() == 0) return false; RowsSelection::iterator current_selection_begin(current_selection->begin()); RowsSelection::iterator current_selection_end(current_selection->end()); // inspect the selected frames, if they are all set, then unset all, else set all bool unset_found = false, changes_made = false; for(RowsSelection::iterator it(current_selection_begin); it != current_selection_end; it++) { if (!markersManager.getMarkerAtFrame(*it)) { unset_found = true; break; } } if (unset_found) { // set all for(RowsSelection::iterator it(current_selection_begin); it != current_selection_end; it++) { if (!markersManager.getMarkerAtFrame(*it)) { if (markersManager.setMarkerAtFrame(*it)) { changes_made = true; pianoRoll.redrawRow(*it); } } } if (changes_made) history.registerMarkersChange(MODTYPE_MARKER_SET, *current_selection_begin, *current_selection->rbegin()); } else { // unset all for(RowsSelection::iterator it(current_selection_begin); it != current_selection_end; it++) { if (markersManager.getMarkerAtFrame(*it)) { markersManager.removeMarkerFromFrame(*it); changes_made = true; pianoRoll.redrawRow(*it); } } if (changes_made) history.registerMarkersChange(MODTYPE_MARKER_REMOVE, *current_selection_begin, *current_selection->rbegin()); } if (changes_made) selection.mustFindCurrentMarker = playback.mustFindCurrentMarker = true; return changes_made; }
void GREENZONE::update() { // keep collecting savestates, this code must be executed at the end of every frame if (taseditorConfig.enableGreenzoning) { collectCurrentState(); } else { // just update Greenzone upper limit if (greenzoneSize <= currFrameCounter) greenzoneSize = currFrameCounter + 1; } // run cleaning from time to time if (clock() > nextCleaningTime) runGreenzoneCleaning(); // also log lag frames if (currFrameCounter > 0) { // lagFlag indicates that lag was in previous frame int old_lagFlag = lagLog.getLagInfoAtFrame(currFrameCounter - 1); // Auto-adjust Input according to lag if (taseditorConfig.autoAdjustInputAccordingToLag && old_lagFlag != LAGGED_UNKNOWN) { if ((old_lagFlag == LAGGED_YES) && !lagFlag) { // there's no more lag on previous frame - shift Input up 1 or more frames adjustUp(); } else if ((old_lagFlag == LAGGED_NO) && lagFlag) { // there's new lag on previous frame - shift Input down 1 frame adjustDown(); } } else { if (lagFlag && (old_lagFlag != LAGGED_YES)) { lagLog.setLagInfo(currFrameCounter - 1, true); // keep current snapshot laglog in touch history.getCurrentSnapshot().laglog.setLagInfo(currFrameCounter - 1, true); } else if (!lagFlag && old_lagFlag != LAGGED_NO) { lagLog.setLagInfo(currFrameCounter - 1, false); // keep current snapshot laglog in touch history.getCurrentSnapshot().laglog.setLagInfo(currFrameCounter - 1, false); } } } }
bool exitTASEditor() { if (!askToSaveProject()) return false; // destroy window taseditorWindow.exit(); disableGeneralKeyboardInput(); // release memory editor.free(); pianoRoll.free(); markersManager.free(); greenzone.free(); bookmarks.free(); branches.free(); popupDisplay.free(); history.free(); playback.stopSeeking(); selection.free(); // restore "eoptions" eoptions = saved_eoptions; // restore autosaves EnableAutosave = saved_EnableAutosave; DoPriority(); // restore frame_display frame_display = saved_frame_display; UpdateCheckedMenuItems(); // switch off TAS Editor mode movieMode = MOVIEMODE_INACTIVE; FCEU_DispMessage("TAS Editor disengaged", 0); FCEUMOV_CreateCleanMovie(); return true; }
void EDITOR::setMarkers() { RowsSelection* current_selection = selection.getCopyOfCurrentRowsSelection(); if (current_selection->size()) { RowsSelection::iterator current_selection_begin(current_selection->begin()); RowsSelection::iterator current_selection_end(current_selection->end()); bool changes_made = false; for(RowsSelection::iterator it(current_selection_begin); it != current_selection_end; it++) { if (!markersManager.getMarkerAtFrame(*it)) { if (markersManager.setMarkerAtFrame(*it)) { changes_made = true; pianoRoll.redrawRow(*it); } } } if (changes_made) { selection.mustFindCurrentMarker = playback.mustFindCurrentMarker = true; history.registerMarkersChange(MODTYPE_MARKER_SET, *current_selection_begin, *current_selection->rbegin()); } } }
bool EDITOR::handleInputColumnSetUsingPattern(int joy, int button) { if (joy < 0 || joy >= joysticksPerFrame[getInputType(currMovieData)]) return false; RowsSelection* current_selection = selection.getCopyOfCurrentRowsSelection(); if (current_selection->size() == 0) return false; RowsSelection::iterator current_selection_begin(current_selection->begin()); RowsSelection::iterator current_selection_end(current_selection->end()); int pattern_offset = 0, current_pattern = taseditorConfig.currentPattern; for(RowsSelection::iterator it(current_selection_begin); it != current_selection_end; it++) { // skip lag frames if (taseditorConfig.autofirePatternSkipsLag && greenzone.lagLog.getLagInfoAtFrame(*it) == LAGGED_YES) continue; currMovieData.records[*it].setBitValue(joy, button, patterns[current_pattern][pattern_offset] != 0); pattern_offset++; if (pattern_offset >= (int)patterns[current_pattern].size()) pattern_offset -= patterns[current_pattern].size(); } int first_changes = history.registerChanges(MODTYPE_PATTERN, *current_selection_begin, *current_selection->rbegin(), 0, patternsNames[current_pattern].c_str()); if (first_changes >= 0) { greenzone.invalidateAndUpdatePlayback(first_changes); return true; } else return false; }
void QNODE::DisplayPolicy(HISTORY& history, int maxDepth, ostream& ostr) const { history.Display(ostr); ostr << ": " << Value.GetValue() << " (" << Value.GetCount() << ")\n"; if (history.Size() >= (uint) maxDepth) return; for (int observation = 0; observation < NumChildren; observation++) { if (Children[observation]) { history.Back().Observation = observation; Children[observation]->DisplayPolicy(history, maxDepth, ostr); } } }
bool ROOMS::LocalMove(STATE &state, const HISTORY &history, int) const { ROOMS_STATE rstate = safe_cast<ROOMS_STATE &>(state); if (GetObservation(rstate) == history.Back().Observation) { return true; } return false; }
void importInputData() { const char filter[] = "FCEUX Movie Files (*.fm2), TAS Editor Projects (*.fm3)\0*.fm2;*.fm3\0All Files (*.*)\0*.*\0\0"; OPENFILENAME ofn; memset(&ofn, 0, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = taseditorWindow.hwndTASEditor; ofn.hInstance = fceu_hInstance; ofn.lpstrTitle = "Import"; ofn.lpstrFilter = filter; char nameo[2048] = {0}; ofn.lpstrFile = nameo; ofn.nMaxFile = 2048; ofn.Flags = OFN_EXPLORER|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_FILEMUSTEXIST; string initdir = FCEU_GetPath(FCEUMKF_MOVIE); ofn.lpstrInitialDir = initdir.c_str(); if (GetOpenFileName(&ofn)) { EMUFILE_FILE ifs(nameo, "rb"); // Load Input to temporary moviedata MovieData md; if (LoadFM2(md, &ifs, ifs.size(), false)) { // loaded successfully, now register Input changes char drv[512], dir[512], name[1024], ext[512]; splitpath(nameo, drv, dir, name, ext); strcat(name, ext); int result = history.registerImport(md, name); if (result >= 0) { greenzone.invalidateAndUpdatePlayback(result); greenzone.lagLog.invalidateFromFrame(result); // keep current snapshot laglog in touch history.getCurrentSnapshot().laglog.invalidateFromFrame(result); } else { MessageBox(taseditorWindow.hwndTASEditor, "Imported movie has the same Input.\nNo changes were made.", "TAS Editor", MB_OK); } } else { FCEUD_PrintError("Error loading movie data!"); } } }
void QNODE::DisplayPolicy(HISTORY& history, int maxDepth, ostream& ostr) const { history.Display(ostr); ImmediateReward.Print("r=", ostr); Observation.Print(", o=", ostr); ostr << std::endl; if (history.Size() >= maxDepth) return; for (int observation = 0; observation < NumChildren; observation++) { if (Children[observation]) { history.Back().Observation = observation; Children[observation]->DisplayPolicy(history, maxDepth, ostr); } } }
bool POCMAN::LocalMove(STATE& state, const HISTORY& history, int stepObs, const STATUS& status) const { _unused(stepObs); _unused(status); POCMAN_STATE& pocstate = safe_cast<POCMAN_STATE&>(state); int numGhosts = Random(1, 3); // Change 1 or 2 ghosts at a time for (int i = 0; i < numGhosts; ++i) { int g = Random(NumGhosts); pocstate.GhostPos[g] = COORD( Random(Maze.GetXSize()), Random(Maze.GetYSize())); if (!Passable(pocstate.GhostPos[g]) || pocstate.GhostPos[g] == pocstate.PocmanPos) return false; } COORD smellPos; for (smellPos.X = -SmellRange; smellPos.X <= SmellRange; smellPos.X++) { for (smellPos.Y = -SmellRange; smellPos.Y <= SmellRange; smellPos.Y++) { COORD pos = pocstate.PocmanPos + smellPos; if (smellPos != COORD(0, 0) && Maze.Inside(pos) && CheckFlag(Maze(pos), E_SEED)) pocstate.Food[Maze.Index(pos)] = Bernoulli(FoodProb * 0.5); } } // Just check the last time-step, don't check for full consistency if (history.Size() == 0) return true; int observation = MakeObservations(pocstate); return history.Back().Observation == observation; }
void createNewProject() { if (!askToSaveProject()) return; static struct NewProjectParameters params; if (DialogBoxParam(fceu_hInstance, MAKEINTRESOURCE(IDD_TASEDITOR_NEWPROJECT), taseditorWindow.hwndTASEditor, newProjectProc, (LPARAM)¶ms) > 0) { FCEUMOV_CreateCleanMovie(); // apply selected options setInputType(currMovieData, params.inputType); applyMovieInputConfig(); if (params.copyCurrentInput) // copy Input from current snapshot (from history) history.getCurrentSnapshot().inputlog.toMovie(currMovieData); if (!params.copyCurrentMarkers) markersManager.reset(); if (params.authorName != L"") currMovieData.comments.push_back(L"author " + params.authorName); // reset Taseditor project.init(); // new project has blank name greenzone.reset(); if (params.copyCurrentInput) // copy LagLog from current snapshot (from history) greenzone.lagLog = history.getCurrentSnapshot().laglog; playback.reset(); playback.restartPlaybackFromZeroGround(); bookmarks.reset(); branches.reset(); history.reset(); pianoRoll.reset(); selection.reset(); editor.reset(); splicer.reset(); recorder.reset(); popupDisplay.reset(); taseditorWindow.redraw(); taseditorWindow.updateCaption(); } }
void VNODE::DisplayValue(HISTORY& history, int maxDepth, ostream& ostr, const std::vector<double> *qvalues) const { if (history.Size() >= maxDepth) return; for (int action = 0; action < NumChildren; action++) { history.Add(action); const QNODE &qnode = Children[action]; if (qnode.Applicable()) { ostr << "n=" << qnode.GetCount() << " "; if (qvalues) { qnode.DisplayValue(history, maxDepth, ostr, &(qvalues->at(action))); } else { qnode.DisplayValue(history, maxDepth, ostr); } } history.Pop(); } }
bool EDITOR::handleInputColumnSet(int joy, int button) { if (joy < 0 || joy >= joysticksPerFrame[getInputType(currMovieData)]) return false; RowsSelection* current_selection = selection.getCopyOfCurrentRowsSelection(); if (current_selection->size() == 0) return false; RowsSelection::iterator current_selection_begin(current_selection->begin()); RowsSelection::iterator current_selection_end(current_selection->end()); //inspect the selected frames, if they are all set, then unset all, else set all bool newValue = false; for(RowsSelection::iterator it(current_selection_begin); it != current_selection_end; it++) { if (!(currMovieData.records[*it].checkBit(joy,button))) { newValue = true; break; } } // apply newValue for(RowsSelection::iterator it(current_selection_begin); it != current_selection_end; it++) currMovieData.records[*it].setBitValue(joy,button,newValue); int first_changes; if (newValue) { first_changes = history.registerChanges(MODTYPE_SET, *current_selection_begin, *current_selection->rbegin()); } else { first_changes = history.registerChanges(MODTYPE_UNSET, *current_selection_begin, *current_selection->rbegin()); } if (first_changes >= 0) { greenzone.invalidateAndUpdatePlayback(first_changes); return true; } else return false; }
void VNODE::DisplayPolicy(HISTORY& history, int maxDepth, ostream& ostr) const { if (history.Size() >= maxDepth) return; // double bestq = -Infinity; int besta = -1; for (int action = 0; action < NumChildren; action++) { // if (Children[action].Dirichlet.GetValue() > bestq) //XXX // { // besta = action; // bestq = Children[action].Dirichlet.GetValue(); // } } if (besta != -1) { history.Add(besta); Children[besta].DisplayPolicy(history, maxDepth, ostr); history.Pop(); } }
void VNODE::DisplayPolicy(HISTORY& history, int maxDepth, ostream& ostr) const { if (history.Size() >= (uint) maxDepth) return; double bestq = -Infinity; int besta = -1; for (int action = 0; action < NumChildren; action++) { if (Children[action].Value.GetValue() > bestq) { besta = action; bestq = Children[action].Value.GetValue(); } } if (besta != -1) { history.Add((uint)besta,0); Children[besta].DisplayPolicy(history, maxDepth, ostr); history.Pop(); } }
// ------------------------------------------------------------------------------------------------- void GREENZONE::adjustUp() { int at = currFrameCounter - 1; // at = the frame above currFrameCounter // find how many consequent lag frames there are int num_frames_to_erase = 0; while (lagLog.getLagInfoAtFrame(at++) == LAGGED_YES) num_frames_to_erase++; if (num_frames_to_erase > 0) { bool markers_changed = false; // delete these frames of lag currMovieData.eraseRecords(currFrameCounter - 1, num_frames_to_erase); lagLog.eraseFrame(currFrameCounter - 1, num_frames_to_erase); if (taseditorConfig.bindMarkersToInput) { if (markersManager.eraseMarker(currFrameCounter - 1, num_frames_to_erase)) markers_changed = true; } // update movie data size, because Playback cursor must always be inside the movie // if movie length is less or equal to currFrame, pad it with empty frames if (((int)currMovieData.records.size() - 1) <= currFrameCounter) currMovieData.insertEmpty(-1, currFrameCounter - ((int)currMovieData.records.size() - 1)); // update Piano Roll (reduce it if needed) pianoRoll.updateLinesCount(); // register changes int first_input_changes = history.registerAdjustLag(currFrameCounter - 1, 0 - num_frames_to_erase); // if Input in the frame above currFrameCounter has changed then invalidate Greenzone (rewind 1 frame back) // also if the frame above currFrameCounter is lag frame then rewind 1 frame (invalidate Greenzone), because maybe this frame also needs lag removal if ((first_input_changes >= 0 && first_input_changes < currFrameCounter) || (lagLog.getLagInfoAtFrame(currFrameCounter - 1) != LAGGED_NO)) { // custom invalidation procedure, not retriggering LostPosition/PauseFrame invalidate(first_input_changes); bool emu_was_paused = (FCEUI_EmulationPaused() != 0); int saved_pause_frame = playback.getPauseFrame(); playback.ensurePlaybackIsInsideGreenzone(); if (saved_pause_frame >= 0) playback.startSeekingToFrame(saved_pause_frame); if (emu_was_paused) playback.pauseEmulation(); } else { // just invalidate Greenzone after currFrameCounter (this is necessary in order to force user to re-emulate everything after the point, because the lag log data after the currFrameCounter is now in unknown state and it should be collected again) invalidate(currFrameCounter); } if (markers_changed) selection.mustFindCurrentMarker = playback.mustFindCurrentMarker = true; } }
bool EDITOR::handleColumnSetUsingPattern() { RowsSelection* current_selection = selection.getCopyOfCurrentRowsSelection(); if (current_selection->size() == 0) return false; RowsSelection::iterator current_selection_begin(current_selection->begin()); RowsSelection::iterator current_selection_end(current_selection->end()); int pattern_offset = 0, current_pattern = taseditorConfig.currentPattern; bool changes_made = false; for(RowsSelection::iterator it(current_selection_begin); it != current_selection_end; it++) { // skip lag frames if (taseditorConfig.autofirePatternSkipsLag && greenzone.lagLog.getLagInfoAtFrame(*it) == LAGGED_YES) continue; if (patterns[current_pattern][pattern_offset]) { if (!markersManager.getMarkerAtFrame(*it)) { if (markersManager.setMarkerAtFrame(*it)) { changes_made = true; pianoRoll.redrawRow(*it); } } } else { if (markersManager.getMarkerAtFrame(*it)) { markersManager.removeMarkerFromFrame(*it); changes_made = true; pianoRoll.redrawRow(*it); } } pattern_offset++; if (pattern_offset >= (int)patterns[current_pattern].size()) pattern_offset -= patterns[current_pattern].size(); } if (changes_made) { history.registerMarkersChange(MODTYPE_MARKER_PATTERN, *current_selection_begin, *current_selection->rbegin(), patternsNames[current_pattern].c_str()); selection.mustFindCurrentMarker = playback.mustFindCurrentMarker = true; return true; } else return false; }
// everyframe function void updateTASEditor() { if (taseditorWindow.hwndTASEditor) { // TAS Editor is engaged // update all modules that need to be updated every frame // the order is somewhat important, e.g. Greenzone must update before Bookmark Set, Piano Roll must update before Selection taseditorWindow.update(); greenzone.update(); recorder.update(); pianoRoll.update(); markersManager.update(); playback.update(); bookmarks.update(); branches.update(); popupDisplay.update(); selection.update(); splicer.update(); history.update(); project.update(); // run Lua functions if needed if (taseditorConfig.enableLuaAutoFunction) TaseditorAutoFunction(); if (mustCallManualLuaFunction) { TaseditorManualFunction(); mustCallManualLuaFunction = false; } } else { // TAS Editor is not engaged TaseditorAutoFunction(); // but we still should run Lua auto function if (mustEngageTaseditor) { char fullname[1000]; strcpy(fullname, curMovieFilename); if (enterTASEditor()) loadProject(fullname); mustEngageTaseditor = false; } } }
bool ROBOT_NAVIGATION::LocalMove(STATE& state, const HISTORY& history, int stepObs, const STATUS& status) const { ROBOT_STATE& robotstate = safe_cast<ROBOT_STATE&>(state); /* * We assume perfect observation of the grid cells immediately surrounding the agent. * As a result, the robot can observe the wall configurations in surrounding squares, * but not its own actual location. */ int obs = 0; for (int i=0; i<8; i++) { int obsx = robotstate.X + ROBOT_NAVIGATION::DeltaObs[i][0]; int obsy = robotstate.Y + ROBOT_NAVIGATION::DeltaObs[i][1]; if (ROBOT_NAVIGATION::Map[obsx][obsy] == 1) obs += 1 << i; } return (obs == history.Back().Observation); }
void EDITOR::setInputUsingPattern(int start, int end, int joy, int button, int consecutivenessTag) { if (joy < 0 || joy >= joysticksPerFrame[getInputType(currMovieData)]) return; if (start > end) { // swap int temp_start = start; start = end; end = temp_start; } if (start < 0) start = end; if (end >= currMovieData.getNumRecords()) return; int pattern_offset = 0, current_pattern = taseditorConfig.currentPattern; bool changes_made = false; bool value; for (int i = start; i <= end; ++i) { // skip lag frames if (taseditorConfig.autofirePatternSkipsLag && greenzone.lagLog.getLagInfoAtFrame(i) == LAGGED_YES) continue; value = (patterns[current_pattern][pattern_offset] != 0); if (currMovieData.records[i].checkBit(joy, button) != value) { changes_made = true; currMovieData.records[i].setBitValue(joy, button, value); } pattern_offset++; if (pattern_offset >= (int)patterns[current_pattern].size()) pattern_offset -= patterns[current_pattern].size(); } if (changes_made) greenzone.invalidateAndUpdatePlayback(history.registerChanges(MODTYPE_PATTERN, start, end, 0, patternsNames[current_pattern].c_str(), consecutivenessTag)); }
void GREENZONE::adjustDown() { int at = currFrameCounter - 1; bool markers_changed = false; // clone frame and insert lag currMovieData.cloneRegion(at, 1); lagLog.insertFrame(at, true, 1); if (taseditorConfig.bindMarkersToInput) { if (markersManager.insertEmpty(at, 1)) markers_changed = true; } // register changes int first_input_changes = history.registerAdjustLag(at, +1); // If Input in the frame above currFrameCounter has changed then invalidate Greenzone (rewind 1 frame back) // This should never actually happen, because we clone the frame, so the Input doesn't change // But the check should remain, in case we decide to insert blank frame instead of cloning if (first_input_changes >= 0 && first_input_changes < currFrameCounter) { // custom invalidation procedure, not retriggering LostPosition/PauseFrame invalidate(first_input_changes); bool emu_was_paused = (FCEUI_EmulationPaused() != 0); int saved_pause_frame = playback.getPauseFrame(); playback.ensurePlaybackIsInsideGreenzone(); if (saved_pause_frame >= 0) playback.startSeekingToFrame(saved_pause_frame); if (emu_was_paused) playback.pauseEmulation(); } else { // just invalidate Greenzone after currFrameCounter invalidate(currFrameCounter); } if (markers_changed) selection.mustFindCurrentMarker = playback.mustFindCurrentMarker = true; }
void ROCKSAMPLE::GeneratePreferred(const STATE& state, const HISTORY& history, vector<int>& actions, const STATUS& status) const { _unused(status); static const bool UseBlindPolicy = false; if (UseBlindPolicy) { actions.push_back(COORD::E_EAST); return; } const ROCKSAMPLE_STATE& rockstate = safe_cast<const ROCKSAMPLE_STATE&>(state); // Sample rocks with more +ve than -ve observations int rock = Grid(rockstate.AgentPos); if (rock >= 0 && !rockstate.Rocks[rock].Collected) { int total = 0; for (int t = 0; t < history.Size(); ++t) { if (history[t].Action == rock + 1 + E_SAMPLE) { if (history[t].Observation == E_GOOD) total++; if (history[t].Observation == E_BAD) total--; } } if (total > 0) { actions.push_back(E_SAMPLE); return; } } // processes the rocks bool all_bad = true; bool north_interesting = false; bool south_interesting = false; bool west_interesting = false; bool east_interesting = false; for (int rock = 0; rock < NumRocks; ++rock) { const ROCKSAMPLE_STATE::ENTRY& entry = rockstate.Rocks[rock]; if (!entry.Collected) { int total = 0; for (int t = 0; t < history.Size(); ++t) { if (history[t].Action == rock + 1 + E_SAMPLE) { if (history[t].Observation == E_GOOD) total++; if (history[t].Observation == E_BAD) total--; } } if (total >= 0) { all_bad = false; if (RockPos[rock].Y > rockstate.AgentPos.Y) north_interesting = true; if (RockPos[rock].Y < rockstate.AgentPos.Y) south_interesting = true; if (RockPos[rock].X < rockstate.AgentPos.X) west_interesting = true; if (RockPos[rock].X > rockstate.AgentPos.X) east_interesting = true; } } } // if all remaining rocks seem bad, then head east if (all_bad) { actions.push_back(COORD::E_EAST); return; } // generate a random legal move, with the exceptions that: // a) there is no point measuring a rock that is already collected // b) there is no point measuring a rock too often // c) there is no point measuring a rock which is clearly bad or good // d) we never sample a rock (since we need to be sure) // e) we never move in a direction that doesn't take us closer to // either the edge of the map or an interesting rock if (rockstate.AgentPos.Y + 1 < Size && north_interesting) actions.push_back(COORD::E_NORTH); if (east_interesting) actions.push_back(COORD::E_EAST); if (rockstate.AgentPos.Y - 1 >= 0 && south_interesting) actions.push_back(COORD::E_SOUTH); if (rockstate.AgentPos.X - 1 >= 0 && west_interesting) actions.push_back(COORD::E_WEST); for (rock = 0; rock < NumRocks; ++rock) { if (!rockstate.Rocks[rock].Collected && rockstate.Rocks[rock].ProbValuable != 0.0 && rockstate.Rocks[rock].ProbValuable != 1.0 && rockstate.Rocks[rock].Measured < 5 && std::abs(rockstate.Rocks[rock].Count) < 2) { actions.push_back(rock + 1 + E_SAMPLE); } } }
void EXPERIMENT::Run() { boost::timer timer; MCTS mcts(Simulator, SearchParams); double undiscountedReturn = 0.0; double discountedReturn = 0.0; double discount = 1.0; bool terminal = false; bool outOfParticles = false; int t; STATE* state = Real.CreateStartState(); if (SearchParams.Verbose >= 1) Real.DisplayState(*state, cout); for (t = 0; t < ExpParams.NumSteps; t++) { int observation; double reward; int action = mcts.SelectAction(); terminal = Real.Step(*state, action, observation, reward); Results.Reward.Add(reward); undiscountedReturn += reward; discountedReturn += reward * discount; discount *= Real.GetDiscount(); if (SearchParams.Verbose >= 1) { Real.DisplayAction(action, cout); Real.DisplayState(*state, cout); Real.DisplayObservation(*state, observation, cout); Real.DisplayReward(reward, cout); } if (terminal) { cout << "Terminated" << endl; break; } outOfParticles = !mcts.Update(action, observation, reward); if (outOfParticles) break; if (timer.elapsed() > ExpParams.TimeOut) { cout << "Timed out after " << t << " steps in " << Results.Time.GetTotal() << "seconds" << endl; break; } } if (outOfParticles) { cout << "Out of particles, finishing episode with SelectRandom" << endl; HISTORY history = mcts.GetHistory(); while (++t < ExpParams.NumSteps) { int observation; double reward; // This passes real state into simulator! // SelectRandom must only use fully observable state // to avoid "cheating" int action = Simulator.SelectRandom(*state, history, mcts.GetStatus()); terminal = Real.Step(*state, action, observation, reward); Results.Reward.Add(reward); undiscountedReturn += reward; discountedReturn += reward * discount; discount *= Real.GetDiscount(); if (SearchParams.Verbose >= 1) { Real.DisplayAction(action, cout); Real.DisplayState(*state, cout); Real.DisplayObservation(*state, observation, cout); Real.DisplayReward(reward, cout); } if (terminal) { cout << "Terminated" << endl; break; } history.Add(action, observation); } } Results.Time.Add(timer.elapsed()); Results.UndiscountedReturn.Add(undiscountedReturn); Results.DiscountedReturn.Add(discountedReturn); cout << "Discounted return = " << discountedReturn << ", average = " << Results.DiscountedReturn.GetMean() << endl; cout << "Undiscounted return = " << undiscountedReturn << ", average = " << Results.UndiscountedReturn.GetMean() << endl; }
// returns true if Taseditor is engaged at the end of the function bool enterTASEditor() { if (taseditorWindow.hwndTASEditor) { // TAS Editor is already engaged, just set focus to its window if (!taseditorConfig.windowIsMaximized) ShowWindow(taseditorWindow.hwndTASEditor, SW_SHOWNORMAL); SetForegroundWindow(taseditorWindow.hwndTASEditor); return true; } else if (FCEU_IsValidUI(FCEUI_TASEDITOR)) { // start TAS Editor // create window taseditorWindow.init(); if (taseditorWindow.hwndTASEditor) { enableGeneralKeyboardInput(); // save "eoptions" saved_eoptions = eoptions; // set "Run in background" eoptions |= EO_BGRUN; // "Set high-priority thread" eoptions |= EO_HIGHPRIO; DoPriority(); // switch off autosaves saved_EnableAutosave = EnableAutosave; EnableAutosave = 0; // switch on frame_display saved_frame_display = frame_display; frame_display = 1; UpdateCheckedMenuItems(); // init modules editor.init(); pianoRoll.init(); selection.init(); splicer.init(); playback.init(); greenzone.init(); recorder.init(); markersManager.init(); project.init(); bookmarks.init(); branches.init(); popupDisplay.init(); history.init(); taseditor_lua.init(); // either start new movie or use current movie if (!FCEUMOV_Mode(MOVIEMODE_RECORD|MOVIEMODE_PLAY) || currMovieData.savestate.size() != 0) { if (currMovieData.savestate.size() != 0) FCEUD_PrintError("This version of TAS Editor doesn't work with movies starting from savestate."); // create new movie FCEUI_StopMovie(); movieMode = MOVIEMODE_TASEDITOR; FCEUMOV_CreateCleanMovie(); playback.restartPlaybackFromZeroGround(); } else { // use current movie to create a new project FCEUI_StopMovie(); movieMode = MOVIEMODE_TASEDITOR; } // if movie length is less or equal to currFrame, pad it with empty frames if (((int)currMovieData.records.size() - 1) < currFrameCounter) currMovieData.insertEmpty(-1, currFrameCounter - ((int)currMovieData.records.size() - 1)); // ensure that movie has correct set of ports/fourscore setInputType(currMovieData, getInputType(currMovieData)); // force the input configuration stored in the movie to apply to FCEUX config applyMovieInputConfig(); // reset some modules that need MovieData info pianoRoll.reset(); recorder.reset(); // create initial snapshot in history history.reset(); // reset Taseditor variables mustCallManualLuaFunction = false; SetFocus(history.hwndHistoryList); // set focus only once, to show blue selection cursor SetFocus(pianoRoll.hwndList); FCEU_DispMessage("TAS Editor engaged", 0); taseditorWindow.redraw(); return true; } else { // couldn't init window return false; } } else { // right now TAS Editor launch is not allowed by emulator return true; } }