{"id":19806680,"url":"https://github.com/timnew/marsrover","last_synced_at":"2026-06-10T12:31:32.962Z","repository":{"id":145702540,"uuid":"141946346","full_name":"timnew/MarsRover","owner":"timnew","description":"Well, this is an archive of some legacy codes that I wrote in roughly 10 years ago.","archived":false,"fork":false,"pushed_at":"2018-07-23T01:34:09.000Z","size":45,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-28T18:01:16.041Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timnew.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-23T01:32:09.000Z","updated_at":"2018-07-23T01:45:05.000Z","dependencies_parsed_at":null,"dependency_job_id":"60059157-7a76-46ca-a99f-a3e15bc6a28c","html_url":"https://github.com/timnew/MarsRover","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/timnew/MarsRover","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timnew%2FMarsRover","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timnew%2FMarsRover/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timnew%2FMarsRover/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timnew%2FMarsRover/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timnew","download_url":"https://codeload.github.com/timnew/MarsRover/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timnew%2FMarsRover/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34153482,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T09:08:10.578Z","updated_at":"2026-06-10T12:31:32.943Z","avatar_url":"https://github.com/timnew.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"Language and Tools\n==========================\nThis solution is my answer for Mars Rovers Problem\nAll application is written in C# 4.0 with Visual Studio 2010 and Expression Blend 4.\nSo to build the solution requires the VS 2010 or .net 4 SDK.\n\nProject Organization\n===========================\nThere are 5 projects included in the solution.\n1. MarsRovers\nMarsRovers is the kernel class library, which contains the simulation engine and any\nother key features related to the simulation.\n\n2. MarsRover.Test\nMarsRover.Test is the unit test project for MarsRovers. And for convenience reason,\nMars Rovers is internal visible to it.\n\n3. MarsRovers.Console\nMarsRovers.Console is a command-line based shell for MarsRovers. It enables user to\nconfig the MarsRovers simulation engine, and review the result.\n\n4. MarsRovers.Wpf\nMarsRovers.Wpf is a super simple wpf application that enables user to watch the simulations\nprocess in visual. For time reason, the app is not in product quality, which is just for fun.\nSince I don't have enough time to design and implement full-functional UI for configuration,\nI uses a tricky way to collect configuration from a command line window.\nJust click the configure button, and type the configuration in command-line as usual.\nThen click Start, then simulation will begin.\n\n5. Windy.Foundation\nIt is actually a subset of classes of my own application framework. It provides some support\nmechanism and features.\n\nA not so brief description of the design\n==================================================================\nClasses in MarsRovers can be divided into following categories:\n1. Models\nClasses in this category, such as Rover, Plateau, is the foundation models for the simulation,\nwhich are abstracted from the problem description.\n\n2. ConfigurationProviders\nConfiguration provider is a adapter class that retrieves the simulation configuration from\ndifferent sources, such as Console or TextReader(actually can be a text file, by wrapping it\nwith StreamReader.) or just a hard-coded configuration. It ensures the capability to extend the\nsimulation engine.\nAfter collection the configuration, then it initializes the models,and drives them into a state ready\nfor simulation.\n\n3. Actions\nIRoverAction is the abstraction of all possible actions that rover can perform. And there are 3 concrete\nactions in project by default: move, turn left and turn right.\nActually I implemented a super lightweight dependency injection mechanism in project, which searches the\nassemblies and instantiates all the actions it found in a global cache, which I called action pool.\nAction can apply to rover to change the rover's state, such as position or orientation. There might be tons\nof redundant actions being used in simulation, but actually there are only few instances cached in the pool.\nFor extensibility purpose, actually the action can be some more complicated action, such as turn back or even\nmove the boundary of plateau. As you can see, to add a new action into system in super easy.\n\n4. Rover Controllers\nIn my solution, the instructions are not assigned to the rover itself, instead I assigned them to a controller,\nthen the controller take the responsibility to parse the instructions and push corresponding action to rover while\ntimer ticks.\nActually, rover controller shouldn't be push actions to rover according to the predefined command. It can works\nin a more intelligent way, such as lead a rover follows another or drives the rover run around the plateau.\nTo introduce such an AI controller is also not too hard.\n\n5. Timers\nTimer is the driver of the simulation, it push time slice to the controllers in a order way, then collects the\nfeedback from controllers to determine where more time slices are needed.\nIt is possible to change the simulation pace by choosing different timers.\nTimer is also extensible, actually, in WPF Shell, I introduce a new type of timer, which ticks depends on a\nDispatcher Timer, which ensure these is no cross thread violation in the simulation.\n\nTimer-Controller-Rover data flow\nActually, I introduced simplified RX framework into the simulation\nengine.\nTimer push the time slice to the controller, and then controller push the corresponding instruction to rover.\nThen rover changes it state, and then push the property changed notification to UI.\nAs you can see, the data flow is not pull-based but push-based, which provides a better control to simulation\ntiming, and the data flow is more smooth than the pull-based.\nAnd there is an interesting design that I'd like to introduce a little bit:\nData in push model can only flows from the observee to observer, which means the data flow in one-way. But timer\nneed the feedback from the controllers to find out whether all the controllers had pushed all the instructions to\nthe rovers.\nTo solve this conflict, I introduce the time slice class, which is a reference type. The timer keep the reference\nto it, and then push it to the controllers. Then the time slices passes through all the controllers, and controllers\nreports their status to time slice. And finally timer check the data in time slice, then it knows what it need to know.\n\nAnd another interesting design: the time slice controller\nI wants to reuse the time slice rather than create a new one each time, which means the properties of time slice should\nbe mutable. At the same time, I don't want controller be able to modify the time slice's property\nwhich means the properties should be read-only.\nTo solve the conflict, I introduces a controller, which is a delegate passed out from time slice internal methods.\nthe controller works a token, objects can modify the properties of time slice in specific way with the token.\n\n\nBuild Instruction\n==========================\nAnd there are 3rd party dependencies involved in the some projects.\nFor some reason, I didn't include the binaries into the repository, instead I use nuget\nto fetch these dependencies while building the project.\nTo build the solution, you should install nuget first and make sure path of nuget has been\nadded into the path environment variable, then everything will be done automatically.\n\nOr you can manually install these packages by nuget or just downloading them from CodePlex\nor Google Code.\n\nHere is the list of 3rd party dependencies:\nMarsRover.Test requires\nxunit version: 1.8.0.1545\nMoq   version: 4.0.10827\n\nMarsRovers.Wpf requires\nMvvm Light toolkit version: 3.0.2\n\nBesides 3rd libraries, the solution also involved the Code Analysis and Code Contract.\nTo enable the full features, a Code Contract VS Plug-in might be necessary.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimnew%2Fmarsrover","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimnew%2Fmarsrover","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimnew%2Fmarsrover/lists"}