diff --git a/Cargo.lock b/Cargo.lock index 766dd08..1eabbd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,35 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "arc-swap" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bytes" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "c2-chacha" version = "0.2.3" @@ -13,6 +43,50 @@ name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "chrono" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "colored" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fnv" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "futures-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "getrandom" version = "0.1.13" @@ -23,16 +97,175 @@ dependencies = [ "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hermit-abi" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "libc" version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "mio" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-named-pipes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-uds" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miow" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "net2" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-integer" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num_cpus" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pin-project-lite" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ppv-lite86" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "proc-macro2" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.7.2" @@ -70,26 +303,235 @@ dependencies = [ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "sdl2" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "sdl2-sys 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sdl2-sys" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "signal-hook-registry" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arc-swap 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "simple_logger" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "colored 1.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "socket2" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tetris" version = "0.1.0" dependencies = [ + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sdl2 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "simple_logger 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "time" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-macros" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "wasi" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [metadata] +"checksum arc-swap 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d663a8e9a99154b5fb793032533f6328da35e23aac63d5c152279aa8ba356825" +"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" +"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +"checksum bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +"checksum chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" +"checksum colored 1.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" +"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a" "checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" +"checksum hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8" +"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" +"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" +"checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" +"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" +"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" +"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" +"checksum pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +"checksum proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" +"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" "checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +"checksum sdl2 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f74124048ea86b5cd50236b2443f6f57cf4625a8e8818009b4e50dbb8729a43" +"checksum sdl2-sys 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c2e1deb61ff274d29fb985017d4611d4004b113676eaa9c06754194caf82094e" +"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" +"checksum simple_logger 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fea0c4611f32f4c2bac73754f22dca1f57e6c1945e0590dae4e5f2a077b92367" +"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +"checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" +"checksum syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" +"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" +"checksum tokio 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "0fa5e81d6bc4e67fe889d5783bd2a128ab2e0cfa487e0be16b6a8d177b101616" +"checksum tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/Cargo.toml b/Cargo.toml index 4e8d54e..d499e36 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,7 @@ edition = "2018" [dependencies] rand = "0.7" +tokio = { version = "0.2", features = ["full"] } +log = "0.4" +simple_logger = "1.6" +sdl2 = { version = "0.33.0", features = ["ttf"] } \ No newline at end of file diff --git a/src/game.rs b/src/game.rs index f8324ac..29fa673 100644 --- a/src/game.rs +++ b/src/game.rs @@ -4,25 +4,123 @@ use crate::playfield::PlayField; use crate::srs::RotationSystem; use crate::srs::SRS; +use crate::tetromino::Position; +use crate::Renderable; +use crate::TICKS_PER_SECOND; +use log::trace; +use sdl2::{render::Canvas, video::Window}; +use std::fmt; -pub struct Game { +// I think this was correct, can't find source +const LINE_CLEAR_DELAY: u64 = TICKS_PER_SECOND as u64 * 41 / 60; + +// Logic is based on 60 ticks / second +pub struct Game { playfield: PlayField, - rotation_system: RS, + rotation_system: SRS, level: u8, - points: u64, + points: u32, + pub tick: u64, + next_gravity_tick: u64, + next_lock_tick: u64, + next_spawn_tick: u64, + is_game_over: bool, } -impl Default for Game { +impl fmt::Debug for Game { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!(f, "level: {}, points: {}", self.level, self.points)?; + writeln!(f, "tick: {}", self.tick)?; + write!(f, "{:?}", self.playfield) + } +} + +impl Default for Game { fn default() -> Self { Game { playfield: PlayField::new(), - rotation_system: RS::default(), - level: 0, + rotation_system: SRS::default(), + level: 1, points: 0, + tick: 0, + next_gravity_tick: 60, + next_lock_tick: 0, + next_spawn_tick: 0, + is_game_over: false, } } } +pub trait Tickable { + fn tick(&mut self); +} + +impl Tickable for Game { + fn tick(&mut self) { + if self.is_game_over() { + return; + } + + self.tick += 1; + match self.tick { + t if t == self.next_spawn_tick => self.spawn_tetromino(), + t if t == self.next_lock_tick => { + // It's possible that the player moved the piece in the meantime. + if !self.playfield.can_active_piece_move_down() { + let positions = self.playfield.lock_active_piece(); + self.is_game_over = + self.is_game_over || positions.iter().all(|Position { x: _, y }| *y < 20); + if self.clear_lines() { + self.next_spawn_tick = self.tick + LINE_CLEAR_DELAY; + } else { + self.spawn_tetromino(); + } + } + } + t if t == self.next_gravity_tick => { + self.playfield.tick_gravity(); + if !self.playfield.can_active_piece_move_down() { + self.update_lock_tick(); + } + self.update_gravity_tick(); + } + _ => (), + } + } +} + +impl Game { + pub fn is_game_over(&self) -> bool { + self.is_game_over || !self.playfield.is_active_piece_in_valid_position() + } + + fn update_gravity_tick(&mut self) { + self.next_gravity_tick = self.tick + TICKS_PER_SECOND as u64; + } + + fn update_lock_tick(&mut self) { + self.next_lock_tick = self.tick + TICKS_PER_SECOND as u64 / 2; + } + + fn spawn_tetromino(&mut self) { + self.playfield.spawn_tetromino(); + self.playfield.tick_gravity(); + self.update_gravity_tick(); + } + + /// Returns if some lines were cleared + fn clear_lines(&mut self) -> bool { + // todo: award points based on how lines were cleared + return false; + } +} + +impl Renderable for Game { + fn render(&self, canvas: &mut Canvas) -> Result<(), String> { + self.playfield.render(canvas) + } +} + trait Controllable { fn move_left(&mut self); fn move_up(&mut self); @@ -34,7 +132,7 @@ trait Controllable { fn hold(&mut self); } -impl Controllable for Game { +impl Controllable for Game { fn move_left(&mut self) {} fn move_up(&mut self) {} fn move_right(&mut self) {} diff --git a/src/graphics.rs b/src/graphics.rs new file mode 100644 index 0000000..63771e0 --- /dev/null +++ b/src/graphics.rs @@ -0,0 +1,12 @@ +use sdl2::pixels::Color; + +pub const CELL_SIZE: u32 = 32; +pub static COLOR_BACKGROUND: Color = Color::RGB(60, 60, 60); +pub static COLOR_CYAN: Color = Color::RGB(0, 255, 255); +pub static COLOR_YELLOW: Color = Color::RGB(255, 255, 0); +pub static COLOR_PURPLE: Color = Color::RGB(255, 0, 255); +pub static COLOR_GREEN: Color = Color::RGB(0, 255, 0); +pub static COLOR_RED: Color = Color::RGB(255, 0, 0); +pub static COLOR_BLUE: Color = Color::RGB(0, 0, 255); +pub static COLOR_ORANGE: Color = Color::RGB(255, 127, 0); +pub static COLOR_GRAY: Color = Color::RGB(100, 100, 100); diff --git a/src/main.rs b/src/main.rs index 55ae187..aea3f15 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,22 +1,58 @@ -use game::Game; -use srs::SRS; +use game::{Game, Tickable}; +use graphics::COLOR_BACKGROUND; +use sdl2::event::Event; +use sdl2::keyboard::Keycode; +use sdl2::{render::Canvas, video::Window}; +use std::time::Duration; +use tokio::time::interval; mod game; +mod graphics; mod playfield; mod random; mod srs; +mod tetromino; -#[derive(Debug, Copy, Clone)] -pub enum Tetromino { - I, - O, - T, - S, - Z, - J, - L, +const TICKS_PER_SECOND: usize = 60; + +pub trait Renderable { + fn render(&self, canvas: &mut Canvas) -> Result<(), String>; } -fn main() { - let mut game: Game = Game::default(); +#[tokio::main] +async fn main() -> Result<(), Box> { + let sdl_context = sdl2::init()?; + let video_subsystem = sdl_context.video()?; + let window = video_subsystem + .window("retris", 800, 800) + .position_centered() + .build()?; + let mut canvas = window.into_canvas().build()?; + let mut event_pump = sdl_context.event_pump()?; + let mut game = Game::default(); + let mut interval = interval(Duration::from_millis(60 / TICKS_PER_SECOND as u64)); + + 'running: while !game.is_game_over() { + for event in event_pump.poll_iter() { + match event { + Event::Quit { .. } + | Event::KeyDown { + keycode: Some(Keycode::Escape), + .. + } => break 'running, + _ => {} + } + } + game.tick(); + canvas.set_draw_color(COLOR_BACKGROUND); + canvas.clear(); + game.render(&mut canvas)?; + canvas.present(); + interval.tick().await; + } + + println!("Game over! Final game state:"); + dbg!(game); + + Ok(()) } diff --git a/src/playfield.rs b/src/playfield.rs index a12b26e..39125a8 100644 --- a/src/playfield.rs +++ b/src/playfield.rs @@ -1,76 +1,187 @@ +use crate::graphics::{CELL_SIZE, COLOR_BACKGROUND}; use crate::random::RandomSystem; -use crate::Tetromino; +use crate::tetromino::Position; +use crate::tetromino::{MinoColor, Tetromino, TetrominoType}; +use crate::Renderable; +use sdl2::{pixels::Color, rect::Rect, render::Canvas, video::Window}; use std::collections::VecDeque; +use std::fmt; -#[derive(Copy, Clone)] -enum MinoColor { - Cyan, - Yellow, - Purple, - Green, - Red, - Blue, - Orange, - Gray, -} +pub const PLAYFIELD_HEIGHT: usize = 20; +pub const PLAYFIELD_WIDTH: usize = 10; + +pub type Matrix = [[Option; PLAYFIELD_WIDTH]; 2 * PLAYFIELD_HEIGHT]; enum Movement { - Rotate, + Rotation, Gravity, Translation, } -pub struct Position { - x: u8, - y: u8, -} - pub struct PlayField { can_swap_hold: bool, - hold_piece: Option, - field: [[Option; 10]; 40], // access via y, x - active_piece: Tetromino, - active_pos: Position, + hold_piece: Option, + field: Matrix, + active_piece: Option, bag: RandomSystem, - next_pieces: VecDeque, + next_pieces: VecDeque, last_movement: Movement, } +impl fmt::Debug for PlayField { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.active_piece { + Some(active_piece) => { + writeln!( + f, + "current piece: {:?} @ {}, {}", + active_piece.piece_type, active_piece.position.x, active_piece.position.y + )?; + } + None => (), + } + + writeln!(f, "next pieces: {:?}", self.next_pieces)?; + let occupied_spaces = self + .active_piece + .and_then(|t| Some(t.get_cur_occupied_spaces())) + .unwrap_or_default(); + for y in PLAYFIELD_HEIGHT..self.field.len() { + write!( + f, + "{} │", + ('a' as usize - PLAYFIELD_HEIGHT + y) as u8 as char + )?; + for x in 0..PLAYFIELD_WIDTH { + if occupied_spaces.contains(&Position::new(x, y)) { + write!(f, "#")?; + } else { + match self.field[y][x] { + Some(t) => write!(f, "{:?}", t)?, + None => write!(f, " ")?, + } + } + } + writeln!(f, "│")?; + } + writeln!(f, " └{}┘", "─".repeat(PLAYFIELD_WIDTH))?; + write!( + f, + " {}", + (0..PLAYFIELD_WIDTH) + .map(|e| e.to_string()) + .collect::>() + .join("") + )?; + Ok(()) + } +} + impl PlayField { pub fn new() -> Self { let mut bag = RandomSystem::new(); - let active_piece = bag.get_tetrino(); + let active_piece = Tetromino::from(bag.get_tetrino()); let mut next_pieces = VecDeque::with_capacity(3); - for _ in 0..next_pieces.len() { + for _ in 0..next_pieces.capacity() { next_pieces.push_back(bag.get_tetrino()); } PlayField { can_swap_hold: true, hold_piece: None, - field: [[None; 10]; 40], - active_piece, - active_pos: Position { x: 0, y: 0 }, + field: [[None; PLAYFIELD_WIDTH]; 2 * PLAYFIELD_HEIGHT], + active_piece: Some(active_piece), bag, next_pieces, last_movement: Movement::Gravity, } } - fn get_new_piece(&mut self) { - self.active_piece = self - .next_pieces - .pop_front() - .expect("visible queue to be populated"); + pub fn spawn_tetromino(&mut self) { + self.active_piece = Some(Tetromino::from( + self.next_pieces + .pop_front() + .expect("visible queue to be populated"), + )); self.next_pieces.push_back(self.bag.get_tetrino()); - self.reset_position(); self.can_swap_hold = true; } - /// Place the current Tetromino at its default spawn position and - /// orientation. Used for hold-swapping or spawning in a new piece. - fn reset_position(&mut self) { - self.last_movement = Movement::Gravity; - unimplemented!(); + pub fn tick_gravity(&mut self) { + match &self.active_piece { + Some(mut active_piece) if self.can_active_piece_move_down() => { + active_piece.position.y += 1; + self.active_piece = Some(active_piece); + } + _ => (), + } + } + + pub fn can_active_piece_move_down(&self) -> bool { + self.active_piece + .and_then(|p| { + Some(p.get_next_occupied_spaces().iter().fold(true, |acc, pos| { + acc && pos.y < self.field.len() + && self.field[pos.y as usize][pos.x as usize].is_none() + })) + }) + .unwrap_or_else(|| false) + } + + pub fn lock_active_piece(&mut self) -> Vec { + match &self.active_piece { + Some(active_piece) => { + let active_color = active_piece.get_color(); + let new_pieces = active_piece.get_cur_occupied_spaces(); + for Position { x, y } in &new_pieces { + self.field[*y][*x] = Some(active_color); + } + + self.active_piece = None; + new_pieces + } + None => panic!("Tried to lock active piece while active piece doesn't exist!"), + } + } + + pub fn is_active_piece_in_valid_position(&self) -> bool { + match self.active_piece { + Some(active_piece) => active_piece.get_cur_occupied_spaces().iter().all(|Position {x, y}| self.field[*y][*x].is_none()), + None => panic!("Tried checking if active piece is in a valid position but active piece doesn't exist") + } + } +} + +impl Renderable for PlayField { + fn render(&self, canvas: &mut Canvas) -> Result<(), String> { + for y in 0..PLAYFIELD_HEIGHT { + for x in 0..PLAYFIELD_WIDTH { + canvas.set_draw_color(Color::RGB(0, 0, 0)); + canvas.fill_rect(Rect::new( + CELL_SIZE as i32 * x as i32, + CELL_SIZE as i32 * y as i32, + CELL_SIZE, + CELL_SIZE, + ))?; + + match self.field[y + PLAYFIELD_HEIGHT][x] { + Some(mino) => canvas.set_draw_color(mino), + None => canvas.set_draw_color(COLOR_BACKGROUND), + } + canvas.fill_rect(Rect::new( + CELL_SIZE as i32 * x as i32 + 2, + CELL_SIZE as i32 * y as i32 + 2, + 28, + 28, + ))?; + } + } + + match self.active_piece { + Some(piece) => piece.render(canvas)?, + None => (), + } + + Ok(()) } } diff --git a/src/random.rs b/src/random.rs index d105fa4..ffc4001 100644 --- a/src/random.rs +++ b/src/random.rs @@ -1,9 +1,9 @@ -use crate::Tetromino; +use crate::tetromino::TetrominoType; use rand::{rngs::ThreadRng, seq::SliceRandom, thread_rng}; pub struct RandomSystem { rng: ThreadRng, - bag: [Tetromino; 7], + bag: [TetrominoType; 7], cur_pos: usize, } @@ -12,12 +12,12 @@ impl RandomSystem { let rng = thread_rng(); RandomSystem { rng: rng, - bag: [Tetromino::I; 7], // Default value, should get init on first get + bag: [TetrominoType::I; 7], // Default value, should get init on first get cur_pos: 0, } } - pub fn get_tetrino(&mut self) -> Tetromino { + pub fn get_tetrino(&mut self) -> TetrominoType { if self.cur_pos == 0 { self.refresh_bag(); } @@ -28,13 +28,13 @@ impl RandomSystem { fn refresh_bag(&mut self) { self.bag = [ - Tetromino::I, - Tetromino::O, - Tetromino::T, - Tetromino::S, - Tetromino::Z, - Tetromino::J, - Tetromino::L, + TetrominoType::I, + TetrominoType::O, + TetrominoType::T, + TetrominoType::S, + TetrominoType::Z, + TetrominoType::J, + TetrominoType::L, ]; self.bag.shuffle(&mut self.rng); self.cur_pos = 0; diff --git a/src/srs.rs b/src/srs.rs index fccbd93..089a95e 100644 --- a/src/srs.rs +++ b/src/srs.rs @@ -1,5 +1,5 @@ -use crate::playfield::{PlayField, Position}; -use crate::Tetromino; +use crate::playfield::PlayField; +use crate::tetromino::{Position, TetrominoType}; #[derive(Copy, Clone)] pub struct Offset { @@ -16,7 +16,7 @@ pub trait RotationSystem { fn default() -> Self; fn get_rotation_offset( - piece: &Tetromino, + piece: &TetrominoType, center: &Position, direction: RotationDirection, playfield: &PlayField, @@ -37,7 +37,7 @@ impl RotationSystem for SRS { } fn get_rotation_offset( - piece: &Tetromino, + piece: &TetrominoType, center: &Position, direction: RotationDirection, playfield: &PlayField, diff --git a/src/tetromino.rs b/src/tetromino.rs new file mode 100644 index 0000000..15aff40 --- /dev/null +++ b/src/tetromino.rs @@ -0,0 +1,258 @@ +use crate::{ + graphics::*, + playfield::{PLAYFIELD_HEIGHT, PLAYFIELD_WIDTH}, + Renderable, +}; +use sdl2::{pixels::Color, rect::Rect, render::Canvas, video::Window}; +use std::fmt; + +#[derive(Copy, Clone)] +pub enum MinoColor { + Cyan, + Yellow, + Purple, + Green, + Red, + Blue, + Orange, + Gray, +} + +impl fmt::Debug for MinoColor { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match self { + Self::Cyan => "c", + Self::Yellow => "y", + Self::Purple => "p", + Self::Green => "g", + Self::Red => "r", + Self::Blue => "b", + Self::Orange => "o", + Self::Gray => "x", + } + ) + } +} + +impl Into for MinoColor { + fn into(self) -> Color { + match self { + Self::Cyan => COLOR_CYAN, + Self::Yellow => COLOR_YELLOW, + Self::Purple => COLOR_PURPLE, + Self::Green => COLOR_GREEN, + Self::Red => COLOR_RED, + Self::Blue => COLOR_BLUE, + Self::Orange => COLOR_ORANGE, + Self::Gray => COLOR_GRAY, + } + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum TetrominoType { + I, + O, + T, + S, + Z, + J, + L, +} + +impl Into for TetrominoType { + fn into(self) -> Color { + match self { + Self::I => COLOR_CYAN, + Self::O => COLOR_YELLOW, + Self::T => COLOR_PURPLE, + Self::S => COLOR_GREEN, + Self::Z => COLOR_RED, + Self::J => COLOR_BLUE, + Self::L => COLOR_ORANGE, + } + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +enum RotationState { + O, // initial state + R, // clockwise rotation + L, // counter-clockwise rotation + U, // 180 deg rotation +} + +impl Default for RotationState { + fn default() -> Self { + RotationState::O + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct Position { + pub x: usize, + pub y: usize, +} + +impl Position { + pub fn new(x: usize, y: usize) -> Position { + Self { + x: x as usize, + y: y as usize, + } + } + + fn offset(&self, x: isize, y: isize) -> Position { + Self { + x: (x + self.x as isize) as usize, + y: (y + self.y as isize) as usize, + } + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct Tetromino { + pub position: Position, + pub piece_type: TetrominoType, + rotation_state: RotationState, +} + +impl Tetromino { + pub fn new(tetromino_type: TetrominoType) -> Self { + Self { + position: Self::get_start_position(tetromino_type), + piece_type: tetromino_type, + rotation_state: RotationState::default(), + } + } + + pub fn get_next_occupied_spaces(&self) -> Vec { + self.get_occupied_spaces(self.position.offset(0, 1)) + } + + pub fn get_cur_occupied_spaces(&self) -> Vec { + self.get_occupied_spaces(self.position) + } + + pub fn get_color(&self) -> MinoColor { + match self.piece_type { + TetrominoType::I => MinoColor::Cyan, + TetrominoType::O => MinoColor::Yellow, + TetrominoType::T => MinoColor::Purple, + TetrominoType::S => MinoColor::Green, + TetrominoType::Z => MinoColor::Red, + TetrominoType::J => MinoColor::Blue, + TetrominoType::L => MinoColor::Orange, + } + } + + fn get_start_position(tetromino_type: TetrominoType) -> Position { + if tetromino_type == TetrominoType::I { + Position::new(PLAYFIELD_WIDTH / 2 - 1, PLAYFIELD_HEIGHT - 1) + } else { + Position::new(PLAYFIELD_WIDTH / 2 - 1, PLAYFIELD_HEIGHT) + } + } + + fn get_occupied_spaces(&self, center: Position) -> Vec { + let mut spaces = vec![center]; + match self.piece_type { + TetrominoType::I => match self.rotation_state { + RotationState::O => spaces.extend_from_slice(&[ + center.offset(-1, 0), + center.offset(1, 0), + center.offset(2, 0), + ]), + RotationState::R => spaces.extend_from_slice(&[ + center.offset(0, -1), + center.offset(0, 1), + center.offset(0, 2), + ]), + RotationState::L => todo!(), + RotationState::U => todo!(), + }, + TetrominoType::J => match self.rotation_state { + RotationState::O => spaces.extend_from_slice(&[ + center.offset(-1, -1), + center.offset(-1, 0), + center.offset(1, 0), + ]), + RotationState::R => todo!(), + RotationState::L => todo!(), + RotationState::U => todo!(), + }, + TetrominoType::L => match self.rotation_state { + RotationState::O => spaces.extend_from_slice(&[ + center.offset(1, -1), + center.offset(-1, 0), + center.offset(1, 0), + ]), + RotationState::R => todo!(), + RotationState::L => todo!(), + RotationState::U => todo!(), + }, + TetrominoType::O => match self.rotation_state { + RotationState::O => spaces.extend_from_slice(&[ + center.offset(0, -1), + center.offset(1, -1), + center.offset(1, 0), + ]), + RotationState::R => todo!(), + RotationState::L => todo!(), + RotationState::U => todo!(), + }, + TetrominoType::S => match self.rotation_state { + RotationState::O => spaces.extend_from_slice(&[ + center.offset(0, -1), + center.offset(1, -1), + center.offset(-1, 0), + ]), + RotationState::R => todo!(), + RotationState::L => todo!(), + RotationState::U => todo!(), + }, + TetrominoType::T => match self.rotation_state { + RotationState::O => spaces.extend_from_slice(&[ + center.offset(0, -1), + center.offset(-1, 0), + center.offset(1, 0), + ]), + RotationState::R => todo!(), + RotationState::L => todo!(), + RotationState::U => todo!(), + }, + TetrominoType::Z => match self.rotation_state { + RotationState::O => spaces.extend_from_slice(&[ + center.offset(-1, -1), + center.offset(0, -1), + center.offset(1, 0), + ]), + RotationState::R => todo!(), + RotationState::L => todo!(), + RotationState::U => todo!(), + }, + } + + spaces + } +} + +impl From for Tetromino { + fn from(tetromino_type: TetrominoType) -> Self { + Self::new(tetromino_type) + } +} + +impl Renderable for Tetromino { + fn render(&self, canvas: &mut Canvas) -> Result<(), String> { + for Position { x, y } in self.get_cur_occupied_spaces() { + canvas.set_draw_color(self.piece_type); + let height = y as isize - PLAYFIELD_HEIGHT as isize; + canvas.fill_rect(Rect::new(32 * x as i32 + 2, 32 * height as i32 + 2, 28, 28))?; + } + Ok(()) + } +}