Initial commit
- Let max. 100 UFOs cross the screen.
This commit is contained in:
		
						commit
						ea6093bd0a
					
				
					 15 changed files with 765 additions and 0 deletions
				
			
		
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | /target | ||||||
							
								
								
									
										10
									
								
								.idea/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								.idea/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | # Default ignored files | ||||||
|  | /shelf/ | ||||||
|  | /workspace.xml | ||||||
|  | # Editor-based HTTP Client requests | ||||||
|  | /httpRequests/ | ||||||
|  | # Datasource local storage ignored files | ||||||
|  | /dataSources/ | ||||||
|  | /dataSources.local.xml | ||||||
|  | # Zeppelin ignored files | ||||||
|  | /ZeppelinRemoteNotebooks/ | ||||||
							
								
								
									
										87
									
								
								.idea/codeStyles/Project.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								.idea/codeStyles/Project.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,87 @@ | ||||||
|  | <component name="ProjectCodeStyleConfiguration"> | ||||||
|  |   <code_scheme name="Project" version="173"> | ||||||
|  |     <option name="ENABLE_SECOND_REFORMAT" value="true" /> | ||||||
|  |     <JavaCodeStyleSettings> | ||||||
|  |       <option name="GENERATE_FINAL_LOCALS" value="true" /> | ||||||
|  |       <option name="GENERATE_FINAL_PARAMETERS" value="true" /> | ||||||
|  |       <option name="REPLACE_INSTANCEOF_AND_CAST" value="true" /> | ||||||
|  |       <option name="ANNOTATION_PARAMETER_WRAP" value="5" /> | ||||||
|  |       <option name="ALIGN_MULTILINE_ANNOTATION_PARAMETERS" value="true" /> | ||||||
|  |       <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="50" /> | ||||||
|  |       <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="50" /> | ||||||
|  |       <option name="RECORD_COMPONENTS_WRAP" value="5" /> | ||||||
|  |       <option name="MULTI_CATCH_TYPES_WRAP" value="5" /> | ||||||
|  |       <option name="JD_ADD_BLANK_AFTER_PARM_COMMENTS" value="true" /> | ||||||
|  |       <option name="JD_ADD_BLANK_AFTER_RETURN" value="true" /> | ||||||
|  |       <option name="JD_P_AT_EMPTY_LINES" value="false" /> | ||||||
|  |       <option name="JD_KEEP_INVALID_TAGS" value="false" /> | ||||||
|  |       <option name="JD_KEEP_EMPTY_PARAMETER" value="false" /> | ||||||
|  |       <option name="JD_KEEP_EMPTY_EXCEPTION" value="false" /> | ||||||
|  |       <option name="JD_KEEP_EMPTY_RETURN" value="false" /> | ||||||
|  |     </JavaCodeStyleSettings> | ||||||
|  |     <ScalaCodeStyleSettings> | ||||||
|  |       <option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" /> | ||||||
|  |     </ScalaCodeStyleSettings> | ||||||
|  |     <codeStyleSettings language="JAVA"> | ||||||
|  |       <option name="RIGHT_MARGIN" value="120" /> | ||||||
|  |       <option name="KEEP_LINE_BREAKS" value="false" /> | ||||||
|  |       <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" /> | ||||||
|  |       <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" /> | ||||||
|  |       <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> | ||||||
|  |       <option name="KEEP_BLANK_LINES_BETWEEN_PACKAGE_DECLARATION_AND_HEADER" value="1" /> | ||||||
|  |       <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" /> | ||||||
|  |       <option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" /> | ||||||
|  |       <option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" /> | ||||||
|  |       <option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" /> | ||||||
|  |       <option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" /> | ||||||
|  |       <option name="ALIGN_MULTILINE_THROWS_LIST" value="true" /> | ||||||
|  |       <option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" /> | ||||||
|  |       <option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" /> | ||||||
|  |       <option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" /> | ||||||
|  |       <option name="CALL_PARAMETERS_WRAP" value="5" /> | ||||||
|  |       <option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" /> | ||||||
|  |       <option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" /> | ||||||
|  |       <option name="METHOD_PARAMETERS_WRAP" value="5" /> | ||||||
|  |       <option name="RESOURCE_LIST_WRAP" value="5" /> | ||||||
|  |       <option name="EXTENDS_LIST_WRAP" value="5" /> | ||||||
|  |       <option name="THROWS_LIST_WRAP" value="5" /> | ||||||
|  |       <option name="METHOD_CALL_CHAIN_WRAP" value="5" /> | ||||||
|  |       <option name="BINARY_OPERATION_WRAP" value="1" /> | ||||||
|  |       <option name="TERNARY_OPERATION_WRAP" value="5" /> | ||||||
|  |       <option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" /> | ||||||
|  |       <option name="FOR_STATEMENT_WRAP" value="5" /> | ||||||
|  |       <option name="ARRAY_INITIALIZER_WRAP" value="5" /> | ||||||
|  |       <option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true" /> | ||||||
|  |       <option name="ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE" value="true" /> | ||||||
|  |       <option name="WRAP_COMMENTS" value="true" /> | ||||||
|  |       <option name="ASSERT_STATEMENT_WRAP" value="5" /> | ||||||
|  |       <option name="IF_BRACE_FORCE" value="3" /> | ||||||
|  |       <option name="DOWHILE_BRACE_FORCE" value="3" /> | ||||||
|  |       <option name="WHILE_BRACE_FORCE" value="3" /> | ||||||
|  |       <option name="FOR_BRACE_FORCE" value="3" /> | ||||||
|  |       <option name="WRAP_LONG_LINES" value="true" /> | ||||||
|  |       <option name="ENUM_CONSTANTS_WRAP" value="2" /> | ||||||
|  |       <option name="SOFT_MARGINS" value="80" /> | ||||||
|  |       <indentOptions> | ||||||
|  |         <option name="LABEL_INDENT_ABSOLUTE" value="true" /> | ||||||
|  |         <option name="USE_RELATIVE_INDENTS" value="true" /> | ||||||
|  |       </indentOptions> | ||||||
|  |       <arrangement> | ||||||
|  |         <groups> | ||||||
|  |           <group> | ||||||
|  |             <type>GETTERS_AND_SETTERS</type> | ||||||
|  |             <order>KEEP</order> | ||||||
|  |           </group> | ||||||
|  |           <group> | ||||||
|  |             <type>OVERRIDDEN_METHODS</type> | ||||||
|  |             <order>KEEP</order> | ||||||
|  |           </group> | ||||||
|  |           <group> | ||||||
|  |             <type>DEPENDENT_METHODS</type> | ||||||
|  |             <order>BREADTH_FIRST</order> | ||||||
|  |           </group> | ||||||
|  |         </groups> | ||||||
|  |       </arrangement> | ||||||
|  |     </codeStyleSettings> | ||||||
|  |   </code_scheme> | ||||||
|  | </component> | ||||||
							
								
								
									
										5
									
								
								.idea/codeStyles/codeStyleConfig.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.idea/codeStyles/codeStyleConfig.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | ||||||
|  | <component name="ProjectCodeStyleConfiguration"> | ||||||
|  |   <state> | ||||||
|  |     <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" /> | ||||||
|  |   </state> | ||||||
|  | </component> | ||||||
							
								
								
									
										6
									
								
								.idea/jpa-buddy.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.idea/jpa-buddy.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project version="4"> | ||||||
|  |   <component name="JpaBuddyIdeaProjectConfig"> | ||||||
|  |     <option name="renamerInitialized" value="true" /> | ||||||
|  |   </component> | ||||||
|  | </project> | ||||||
							
								
								
									
										9
									
								
								.idea/misc.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.idea/misc.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project version="4"> | ||||||
|  |   <component name="ProjectRootManager"> | ||||||
|  |     <output url="file://$PROJECT_DIR$/out" /> | ||||||
|  |   </component> | ||||||
|  |   <component name="ProjectType"> | ||||||
|  |     <option name="id" value="jpab" /> | ||||||
|  |   </component> | ||||||
|  | </project> | ||||||
							
								
								
									
										8
									
								
								.idea/modules.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.idea/modules.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project version="4"> | ||||||
|  |   <component name="ProjectModuleManager"> | ||||||
|  |     <modules> | ||||||
|  |       <module fileurl="file://$PROJECT_DIR$/rust-ufo.iml" filepath="$PROJECT_DIR$/rust-ufo.iml" /> | ||||||
|  |     </modules> | ||||||
|  |   </component> | ||||||
|  | </project> | ||||||
							
								
								
									
										12
									
								
								.idea/php.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.idea/php.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project version="4"> | ||||||
|  |   <component name="MessDetectorOptionsConfiguration"> | ||||||
|  |     <option name="transferred" value="true" /> | ||||||
|  |   </component> | ||||||
|  |   <component name="PHPCSFixerOptionsConfiguration"> | ||||||
|  |     <option name="transferred" value="true" /> | ||||||
|  |   </component> | ||||||
|  |   <component name="PHPCodeSnifferOptionsConfiguration"> | ||||||
|  |     <option name="transferred" value="true" /> | ||||||
|  |   </component> | ||||||
|  | </project> | ||||||
							
								
								
									
										6
									
								
								.idea/vcs.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.idea/vcs.xml
									
										
									
										generated
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project version="4"> | ||||||
|  |   <component name="VcsDirectoryMappings"> | ||||||
|  |     <mapping directory="" vcs="Git" /> | ||||||
|  |   </component> | ||||||
|  | </project> | ||||||
							
								
								
									
										297
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										297
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,297 @@ | ||||||
|  | # This file is automatically @generated by Cargo. | ||||||
|  | # It is not intended for manual editing. | ||||||
|  | version = 3 | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "autocfg" | ||||||
|  | version = "1.1.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "bitflags" | ||||||
|  | version = "1.3.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "cfg-if" | ||||||
|  | version = "1.0.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "crossterm" | ||||||
|  | version = "0.25.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" | ||||||
|  | dependencies = [ | ||||||
|  |  "bitflags", | ||||||
|  |  "crossterm_winapi", | ||||||
|  |  "libc", | ||||||
|  |  "mio", | ||||||
|  |  "parking_lot", | ||||||
|  |  "signal-hook", | ||||||
|  |  "signal-hook-mio", | ||||||
|  |  "winapi", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "crossterm_winapi" | ||||||
|  | version = "0.9.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" | ||||||
|  | dependencies = [ | ||||||
|  |  "winapi", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "getrandom" | ||||||
|  | version = "0.2.8" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" | ||||||
|  | dependencies = [ | ||||||
|  |  "cfg-if", | ||||||
|  |  "libc", | ||||||
|  |  "wasi", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "libc" | ||||||
|  | version = "0.2.139" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "lock_api" | ||||||
|  | version = "0.4.9" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" | ||||||
|  | dependencies = [ | ||||||
|  |  "autocfg", | ||||||
|  |  "scopeguard", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "log" | ||||||
|  | version = "0.4.17" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" | ||||||
|  | dependencies = [ | ||||||
|  |  "cfg-if", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "mio" | ||||||
|  | version = "0.8.5" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" | ||||||
|  | dependencies = [ | ||||||
|  |  "libc", | ||||||
|  |  "log", | ||||||
|  |  "wasi", | ||||||
|  |  "windows-sys", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "parking_lot" | ||||||
|  | version = "0.12.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" | ||||||
|  | dependencies = [ | ||||||
|  |  "lock_api", | ||||||
|  |  "parking_lot_core", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "parking_lot_core" | ||||||
|  | version = "0.9.5" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" | ||||||
|  | dependencies = [ | ||||||
|  |  "cfg-if", | ||||||
|  |  "libc", | ||||||
|  |  "redox_syscall", | ||||||
|  |  "smallvec", | ||||||
|  |  "windows-sys", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "ppv-lite86" | ||||||
|  | version = "0.2.17" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "rand" | ||||||
|  | version = "0.8.5" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" | ||||||
|  | dependencies = [ | ||||||
|  |  "libc", | ||||||
|  |  "rand_chacha", | ||||||
|  |  "rand_core", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "rand_chacha" | ||||||
|  | version = "0.3.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" | ||||||
|  | dependencies = [ | ||||||
|  |  "ppv-lite86", | ||||||
|  |  "rand_core", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "rand_core" | ||||||
|  | version = "0.6.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" | ||||||
|  | dependencies = [ | ||||||
|  |  "getrandom", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "redox_syscall" | ||||||
|  | version = "0.2.16" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" | ||||||
|  | dependencies = [ | ||||||
|  |  "bitflags", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "rust-ufo" | ||||||
|  | version = "0.1.0" | ||||||
|  | dependencies = [ | ||||||
|  |  "crossterm", | ||||||
|  |  "rand", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "scopeguard" | ||||||
|  | version = "1.1.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "signal-hook" | ||||||
|  | version = "0.3.14" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" | ||||||
|  | dependencies = [ | ||||||
|  |  "libc", | ||||||
|  |  "signal-hook-registry", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "signal-hook-mio" | ||||||
|  | version = "0.2.3" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" | ||||||
|  | dependencies = [ | ||||||
|  |  "libc", | ||||||
|  |  "mio", | ||||||
|  |  "signal-hook", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "signal-hook-registry" | ||||||
|  | version = "1.4.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" | ||||||
|  | dependencies = [ | ||||||
|  |  "libc", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "smallvec" | ||||||
|  | version = "1.10.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "wasi" | ||||||
|  | version = "0.11.0+wasi-snapshot-preview1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "winapi" | ||||||
|  | version = "0.3.9" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" | ||||||
|  | dependencies = [ | ||||||
|  |  "winapi-i686-pc-windows-gnu", | ||||||
|  |  "winapi-x86_64-pc-windows-gnu", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "winapi-i686-pc-windows-gnu" | ||||||
|  | version = "0.4.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "winapi-x86_64-pc-windows-gnu" | ||||||
|  | version = "0.4.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "windows-sys" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" | ||||||
|  | dependencies = [ | ||||||
|  |  "windows_aarch64_gnullvm", | ||||||
|  |  "windows_aarch64_msvc", | ||||||
|  |  "windows_i686_gnu", | ||||||
|  |  "windows_i686_msvc", | ||||||
|  |  "windows_x86_64_gnu", | ||||||
|  |  "windows_x86_64_gnullvm", | ||||||
|  |  "windows_x86_64_msvc", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "windows_aarch64_gnullvm" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "windows_aarch64_msvc" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "windows_i686_gnu" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "windows_i686_msvc" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "windows_x86_64_gnu" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "windows_x86_64_gnullvm" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "windows_x86_64_msvc" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" | ||||||
							
								
								
									
										10
									
								
								Cargo.toml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								Cargo.toml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | [package] | ||||||
|  | name = "rust-ufo" | ||||||
|  | version = "0.1.0" | ||||||
|  | edition = "2021" | ||||||
|  | 
 | ||||||
|  | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||||
|  | 
 | ||||||
|  | [dependencies] | ||||||
|  | crossterm = "0.25.0" | ||||||
|  | rand = "0.8.5" | ||||||
							
								
								
									
										12
									
								
								rust-ufo.iml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								rust-ufo.iml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <module type="RUST_MODULE" version="4"> | ||||||
|  |   <component name="NewModuleRootManager" inherit-compiler-output="true"> | ||||||
|  |     <exclude-output /> | ||||||
|  |     <content url="file://$MODULE_DIR$"> | ||||||
|  |       <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/target" /> | ||||||
|  |     </content> | ||||||
|  |     <orderEntry type="inheritedJdk" /> | ||||||
|  |     <orderEntry type="sourceFolder" forTests="false" /> | ||||||
|  |   </component> | ||||||
|  | </module> | ||||||
							
								
								
									
										77
									
								
								src/main.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/main.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,77 @@ | ||||||
|  | use std::thread; | ||||||
|  | use std::time::Duration; | ||||||
|  | 
 | ||||||
|  | use rand::Rng; | ||||||
|  | 
 | ||||||
|  | use crate::Direction::{Down, Left, Right, Up}; | ||||||
|  | use crate::movables::{Movable, Ufo}; | ||||||
|  | 
 | ||||||
|  | mod movables; | ||||||
|  | mod terminal; | ||||||
|  | 
 | ||||||
|  | const WIDTH: u16 = 160; | ||||||
|  | const HEIGHT: u16 = 40; | ||||||
|  | const HEADER_ROW: u16 = 0; | ||||||
|  | const FOOTER_ROW: u16 = HEIGHT - 1; | ||||||
|  | const TANK_ROW: u16 = FOOTER_ROW - 1; | ||||||
|  | const MIN_UFO_ROW: u16 = 1; | ||||||
|  | const MAX_UFO_ROW: u16 = TANK_ROW - 5; | ||||||
|  | const DELAY: Duration = Duration::from_millis(10); | ||||||
|  | const UFO_STR: &str = "<=000=>"; | ||||||
|  | const TANK_STR: &str = "⊆≡≣🠭≣≡⊇"; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | fn main() { | ||||||
|  |     let terminal = terminal::setup(); | ||||||
|  |     const MAX_UFOS: u8 = 100; | ||||||
|  |     let mut ufos = vec![Ufo::create(), Ufo::create(), Ufo::create(), Ufo::create(), Ufo::create()]; | ||||||
|  |     let mut n_ufos = ufos.len() as u8; | ||||||
|  |     loop { | ||||||
|  |         let iter_mut = ufos.iter_mut(); | ||||||
|  |         for x in iter_mut { | ||||||
|  |             x.mov(Direction::Left); | ||||||
|  |             x.draw(); | ||||||
|  |         } | ||||||
|  |         if rand::thread_rng().gen_bool(0.1) && n_ufos < MAX_UFOS { | ||||||
|  |             ufos.push(Ufo::create()); | ||||||
|  |             n_ufos += 1; | ||||||
|  |         } | ||||||
|  |         ufos.retain(|ufo| ufo.is_on_screen()); | ||||||
|  |         if ufos.is_empty() { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         thread::sleep(DELAY); | ||||||
|  |     } | ||||||
|  |     // for _ in 0..N_UFOS {
 | ||||||
|  |     //     let mut ufo = Ufo::create();
 | ||||||
|  |     //     while ufo.is_on_screen() {
 | ||||||
|  |     //         ufo.mov(Direction::Left);
 | ||||||
|  |     //         ufo.draw();
 | ||||||
|  |     //         thread::sleep(DELAY);
 | ||||||
|  |     //     }
 | ||||||
|  |     // }
 | ||||||
|  | 
 | ||||||
|  |     terminal::restore(terminal); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn tank_at(col: u16) { | ||||||
|  |     terminal::print_str_at(col, TANK_ROW, TANK_STR); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub enum Direction { | ||||||
|  |     Left, | ||||||
|  |     Right, | ||||||
|  |     Up, | ||||||
|  |     Down, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Direction { | ||||||
|  |     fn invert(&self) -> Direction { | ||||||
|  |         match self { | ||||||
|  |             Left => Right, | ||||||
|  |             Right => Left, | ||||||
|  |             Up => Down, | ||||||
|  |             Down => Up | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										116
									
								
								src/movables.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/movables.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,116 @@ | ||||||
|  | use rand::Rng; | ||||||
|  | 
 | ||||||
|  | use crate::{Direction, MAX_UFO_ROW, MIN_UFO_ROW, TANK_STR, UFO_STR, WIDTH}; | ||||||
|  | use crate::Direction::{Down, Left, Right}; | ||||||
|  | use crate::terminal::print_str_at; | ||||||
|  | 
 | ||||||
|  | pub trait Movable<T> { | ||||||
|  |     fn create() -> T; | ||||||
|  |     fn mov(&mut self, direction: Direction); | ||||||
|  |     fn draw(&self); | ||||||
|  |     fn is_on_screen(&self) -> bool; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Movable<Ufo> for Ufo { | ||||||
|  |     fn create() -> Ufo { | ||||||
|  |         let mut rng = rand::thread_rng(); | ||||||
|  |         let direction: Direction = if rng.gen() { Left } else { Right }; | ||||||
|  |         let row = rng.gen_range(MIN_UFO_ROW..=MAX_UFO_ROW); | ||||||
|  |         let column = match direction { | ||||||
|  |             // If the UFO is moving right, we will initially place it just at the left edge.
 | ||||||
|  |             Right => -(UFO_STR.len() as i16) + 1, | ||||||
|  |             // If the UFO is moving left, we will initially place it just at the right edge.
 | ||||||
|  |             Left => WIDTH as i16 - 1, | ||||||
|  |             // Above, we're creating either a Left or a Right direction value. So, we CANNOT get here. Hence: PANIC!
 | ||||||
|  |             _ => panic!("Programming error. We're not supposed to get here.") | ||||||
|  |         }; | ||||||
|  |         Ufo { row, column, direction } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn mov(&mut self, direction: Direction) { | ||||||
|  |         let ufo_str_len = UFO_STR.len() as i16; | ||||||
|  | 
 | ||||||
|  |         match direction { | ||||||
|  |             Down => { todo!("Implement crash movement (down + direction)") } | ||||||
|  |             _ => { | ||||||
|  |                 match self.direction { | ||||||
|  |                     Left => { | ||||||
|  |                         if self.column >= -ufo_str_len { | ||||||
|  |                             self.column -= 1; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     Right => { | ||||||
|  |                         if self.column < WIDTH as i16 { | ||||||
|  |                             self.column += 1; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     _ => { /* Ignore, this can't be the case. */ } | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn draw(&self) { | ||||||
|  |         let mut body: String; | ||||||
|  |         let ufo_str_len = UFO_STR.len() as i16; | ||||||
|  | 
 | ||||||
|  |         if self.column < -ufo_str_len { | ||||||
|  |             // left outside
 | ||||||
|  |             body = String::new(); | ||||||
|  |         } else if self.column < 0 { | ||||||
|  |             // left transitioning in/out
 | ||||||
|  |             body = String::new(); | ||||||
|  |         } else if self.column < (WIDTH as i16 - ufo_str_len) { | ||||||
|  |             // normal range
 | ||||||
|  |             body = String::from(UFO_STR); | ||||||
|  |             match self.direction { | ||||||
|  |                 Left => { body.push(' ') } | ||||||
|  |                 Right => { body = String::from(" ") + body.as_str() } | ||||||
|  |                 Down => { todo!("How do we handle the downward movement?") } | ||||||
|  |                 _ => {} | ||||||
|  |             } | ||||||
|  |             let max_len = WIDTH as i16 - self.column; | ||||||
|  |             body.truncate(max_len as usize) | ||||||
|  |         } else if self.column < WIDTH as i16 { | ||||||
|  |             // right transitioning in/out
 | ||||||
|  |             body = String::new(); | ||||||
|  |         } else { | ||||||
|  |             // right outside
 | ||||||
|  |             body = String::new(); | ||||||
|  |         } | ||||||
|  |         print_str_at(if self.column < 0 { 0 } else { self.column as u16 }, self.row, body.as_str()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn is_on_screen(&self) -> bool { | ||||||
|  |         self.column > -(UFO_STR.len() as i16) && self.column < WIDTH as i16 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Movable<Tank> for Tank { | ||||||
|  |     fn create() -> Tank { | ||||||
|  |         let column = (WIDTH - TANK_STR.len() as u16) / 2; | ||||||
|  |         Tank { column } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn mov(&mut self, direction: Direction) { | ||||||
|  |         todo!("Implement tank movement") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn draw(&self) { | ||||||
|  |         todo!("Implement drawing tank") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn is_on_screen(&self) -> bool { | ||||||
|  |         todo!("Implement tank visibility check") | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub struct Ufo { | ||||||
|  |     row: u16, | ||||||
|  |     column: i16, | ||||||
|  |     direction: Direction, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub struct Tank { | ||||||
|  |     column: u16, | ||||||
|  | } | ||||||
							
								
								
									
										109
									
								
								src/terminal.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/terminal.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,109 @@ | ||||||
|  | use std::io::{stdout, Write}; | ||||||
|  | 
 | ||||||
|  | use crossterm::{execute, queue}; | ||||||
|  | use crossterm::cursor::{Hide, MoveTo, RestorePosition, SavePosition, Show}; | ||||||
|  | use crossterm::style::Print; | ||||||
|  | use crossterm::terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen, SetSize, size}; | ||||||
|  | 
 | ||||||
|  | use crate::{FOOTER_ROW, HEADER_ROW, HEIGHT, WIDTH}; | ||||||
|  | 
 | ||||||
|  | pub struct Terminal { | ||||||
|  |     cols: u16, | ||||||
|  |     rows: u16, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn setup() -> Terminal { | ||||||
|  |     let (cols, rows) = size() | ||||||
|  |         .expect("Failed to get terminal screen size"); | ||||||
|  | 
 | ||||||
|  |     execute!( | ||||||
|  |         stdout(), | ||||||
|  |         EnterAlternateScreen, | ||||||
|  |         SetSize(WIDTH, HEIGHT), | ||||||
|  |         Hide | ||||||
|  |     ).expect("Failed to set up terminal screen"); | ||||||
|  |     enable_raw_mode() | ||||||
|  |         .expect("Failed to enable raw terminal mode"); | ||||||
|  | 
 | ||||||
|  |     write_header(); | ||||||
|  |     write_footer(); | ||||||
|  |     Terminal { cols, rows } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn restore(terminal: Terminal) { | ||||||
|  |     disable_raw_mode() | ||||||
|  |         .expect("Failed to disable raw terminal mode"); | ||||||
|  |     execute!( | ||||||
|  |         stdout(), | ||||||
|  |         SetSize(terminal.cols, terminal.rows), | ||||||
|  |         Show, | ||||||
|  |         LeaveAlternateScreen | ||||||
|  |     ) | ||||||
|  |         .expect("Failed to tear down terminal screen"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn write_header() { | ||||||
|  |     queue!( | ||||||
|  |         stdout(), | ||||||
|  |         MoveTo(0,HEADER_ROW), | ||||||
|  |         Print(center_text("UFO goes RUST! ** by fritteli, ufo@fritteli.ch ** Have fun!", None)) | ||||||
|  |     ).expect("Failed to write to terminal"); | ||||||
|  |     stdout().flush().expect("Failed to write to terminal"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn write_footer() { | ||||||
|  |     queue!( | ||||||
|  |         stdout(), | ||||||
|  |         MoveTo(0,FOOTER_ROW), | ||||||
|  |         Print(center_text("v0.0.0-dev", None)) | ||||||
|  |     ).expect("Failed to write to terminal"); | ||||||
|  |     stdout().flush().expect("Failed to write to terminal"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn center_text(text: &str, filler: Option<&str>) -> String { | ||||||
|  |     let length = text.len(); | ||||||
|  |     let surplus = (WIDTH as i16) - (length as i16) - 2; | ||||||
|  |     if surplus < 0 { | ||||||
|  |         return String::from(text); | ||||||
|  |     } | ||||||
|  |     let left: usize = (surplus as usize) / 2; | ||||||
|  |     let right: usize; | ||||||
|  |     if surplus % 2 == 0 { | ||||||
|  |         right = left; | ||||||
|  |     } else { | ||||||
|  |         right = left + 1; | ||||||
|  |     } | ||||||
|  |     let left_fill = filler.unwrap_or("=").repeat(left); | ||||||
|  |     let right_fill = filler.unwrap_or("=").repeat(right); | ||||||
|  |     format!("{} {} {}", left_fill, text, right_fill) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn print_char_at(col: u16, row: u16, char: char) { | ||||||
|  |     execute!( | ||||||
|  |         stdout(), | ||||||
|  |         SavePosition, | ||||||
|  |         MoveTo(col, row), | ||||||
|  |         Print(char), | ||||||
|  |         RestorePosition | ||||||
|  |     ) | ||||||
|  |         .expect("Failed to print char to terminal"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn print_str_at(col: u16, row: u16, s: &str) { | ||||||
|  |     execute!( | ||||||
|  |         stdout(), | ||||||
|  |         SavePosition, | ||||||
|  |         MoveTo(col, row), | ||||||
|  |         Print(s), | ||||||
|  |         RestorePosition | ||||||
|  |     ) | ||||||
|  |         .expect("Failed to print string to terminal"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn clear_pos(col: u16, row: u16) { | ||||||
|  |     print_char_at(col, row, ' '); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn clear_stretch(col: u16, row: u16, len: usize) { | ||||||
|  |     print_str_at(col, row, " ".repeat(len).as_str()); | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue