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
vendored
Normal file
10
.idea/.gitignore
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
Normal file
87
.idea/codeStyles/Project.xml
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
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
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
Normal file
6
.idea/jpa-buddy.xml
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
Normal file
9
.idea/misc.xml
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
Normal file
8
.idea/modules.xml
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
Normal file
12
.idea/php.xml
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
Normal file
6
.idea/vcs.xml
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…
Reference in a new issue