commit d8b781011bcf30f6fe044a67e1de1280612b2699 Author: Eason <30045503+Eason0729@users.noreply.github.com> Date: Wed Jun 12 16:09:12 2024 +0800 reinit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b057a6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +__pycache__ +/output1 +/output2 +dataset +*.so +/train diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..cd3dfc4 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,3590 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "ash" +version = "0.37.3+1.3.251" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" +dependencies = [ + "libloading 0.7.4", +] + +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bincode" +version = "2.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f11ea1a0346b94ef188834a65c068a03aec181c94896d481d7a0a40d85b0ce95" +dependencies = [ + "serde", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "burn" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3960b57a6ad4baf54d1dba766965e4559c4b9a8f391107fee5de29db57265840" +dependencies = [ + "burn-core", + "burn-train", +] + +[[package]] +name = "burn-autodiff" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9479c28bdce3f2b1541f0a9215628f6256b5f3d66871192a3c56d55171d28e" +dependencies = [ + "burn-common", + "burn-tensor", + "derive-new", + "log", + "spin", +] + +[[package]] +name = "burn-candle" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d811c54fa6d9beb38808a1aabd9515c39090720cae572d54f25c041b1702e8fd" +dependencies = [ + "burn-tensor", + "candle-core", + "derive-new", + "half", +] + +[[package]] +name = "burn-common" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9540b2f45a2d337220e702d7a87572c8e1c78db91a200b22924a8c4a6e9be4" +dependencies = [ + "async-trait", + "derive-new", + "getrandom", + "rand", + "serde", + "spin", + "uuid", + "web-time", +] + +[[package]] +name = "burn-compute" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e890d8999b25a1a090c2afe198243fc79f0a299efb531a4871c084b0ab9fa11" +dependencies = [ + "burn-common", + "derive-new", + "dirs", + "hashbrown 0.14.5", + "log", + "md5", + "serde", + "serde_json", + "spin", + "web-time", +] + +[[package]] +name = "burn-core" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8af6bc0afe55a57ff0b08f52302df4e3d09f96805a4f1e15c521f1082cb02b4f" +dependencies = [ + "bincode 2.0.0-rc.3", + "burn-autodiff", + "burn-candle", + "burn-common", + "burn-dataset", + "burn-derive", + "burn-ndarray", + "burn-tch", + "burn-tensor", + "burn-wgpu", + "derive-new", + "flate2", + "half", + "hashbrown 0.14.5", + "log", + "num-traits", + "rand", + "rmp-serde", + "serde", + "serde_json", + "spin", +] + +[[package]] +name = "burn-dataset" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3feae7766b56e947d38ac4d6903388270d848609339a147a513145703426f6db" +dependencies = [ + "csv", + "derive-new", + "dirs", + "gix-tempfile", + "image", + "r2d2", + "r2d2_sqlite", + "rand", + "rmp-serde", + "rusqlite", + "sanitize-filename", + "serde", + "serde_json", + "serde_rusqlite", + "strum", + "strum_macros", + "tempfile", + "thiserror", +] + +[[package]] +name = "burn-derive" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8618ac2c171c7054ffd3ce8da15c3d4b11dc805eb393065c74c05882ef79d931" +dependencies = [ + "derive-new", + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "burn-fusion" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d77b882d131a67d15f91b915fb3e0a5add73547e7352310d33c877fbe77c79e" +dependencies = [ + "burn-common", + "burn-tensor", + "derive-new", + "hashbrown 0.14.5", + "log", + "serde", + "spin", +] + +[[package]] +name = "burn-jit" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cb62a93030a690c329b95c01b43e3064a4bd36031e9111d537641d36e42f3ac" +dependencies = [ + "burn-common", + "burn-compute", + "burn-fusion", + "burn-tensor", + "bytemuck", + "derive-new", + "hashbrown 0.14.5", + "log", + "num-traits", + "rand", + "serde", + "spin", + "text_placeholder", +] + +[[package]] +name = "burn-ndarray" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f40bb0b5938937a721045752f1ec1baee8a873429fd17e6e6f2155c6cdf33a" +dependencies = [ + "burn-autodiff", + "burn-common", + "burn-tensor", + "derive-new", + "libm", + "matrixmultiply", + "ndarray", + "num-traits", + "rand", + "rayon", + "spin", +] + +[[package]] +name = "burn-tch" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cb9c2b547499a3d990e93b950965b9a478edfec4a7bf98d5d4412ff8c897129" +dependencies = [ + "burn-tensor", + "half", + "libc", + "rand", + "tch", +] + +[[package]] +name = "burn-tensor" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa19c21f54e1a189be3bbaec45efafdf1c89b2763710b381c9f32ae25e7dbe8" +dependencies = [ + "burn-common", + "derive-new", + "half", + "hashbrown 0.14.5", + "num-traits", + "rand", + "rand_distr", + "serde", +] + +[[package]] +name = "burn-train" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a0014ee82ef967bd82dda378cfaf340f255c39c729e29ac3bc65d3107e4c7ee" +dependencies = [ + "burn-core", + "crossterm", + "derive-new", + "log", + "nvml-wrapper", + "ratatui", + "serde", + "sysinfo", + "systemstat", + "tracing-appender", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "burn-wgpu" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1575890471123109c6aeb725c52ac649fa9e0013e2303f57dc534d5e0cb857e5" +dependencies = [ + "burn-common", + "burn-compute", + "burn-fusion", + "burn-jit", + "burn-tensor", + "bytemuck", + "derive-new", + "futures-intrusive", + "hashbrown 0.14.5", + "log", + "pollster", + "wgpu", +] + +[[package]] +name = "bytemuck" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytesize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "candle-core" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f1b20174c1707e20f4cb364a355b449803c03e9b0c9193324623cf9787a4e00" +dependencies = [ + "byteorder", + "gemm", + "half", + "memmap2", + "num-traits", + "num_cpus", + "rand", + "rand_distr", + "rayon", + "safetensors 0.4.3", + "thiserror", + "yoke", + "zip", +] + +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + +[[package]] +name = "cc" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +dependencies = [ + "jobserver", + "libc", + "once_cell", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "com" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" +dependencies = [ + "com_macros", +] + +[[package]] +name = "com_macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" +dependencies = [ + "com_macros_support", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "com_macros_support" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crossterm" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +dependencies = [ + "bitflags 2.5.0", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "d3d12" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307" +dependencies = [ + "bitflags 2.5.0", + "libloading 0.8.3", + "winapi", +] + +[[package]] +name = "darling" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.65", +] + +[[package]] +name = "darling_macro" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive-new" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dyn-stack" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e53799688f5632f364f8fb387488dd05db9fe45db7011be066fc20e7027f8b" +dependencies = [ + "bytemuck", + "reborrow", +] + +[[package]] +name = "either" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" + +[[package]] +name = "enum-as-inner" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "faster-hex" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" +dependencies = [ + "serde", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "fdeflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "gemm" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab24cc62135b40090e31a76a9b2766a501979f3070fa27f689c27ec04377d32" +dependencies = [ + "dyn-stack", + "gemm-c32", + "gemm-c64", + "gemm-common", + "gemm-f16", + "gemm-f32", + "gemm-f64", + "num-complex", + "num-traits", + "paste", + "raw-cpuid", + "seq-macro", +] + +[[package]] +name = "gemm-c32" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9c030d0b983d1e34a546b86e08f600c11696fde16199f971cd46c12e67512c0" +dependencies = [ + "dyn-stack", + "gemm-common", + "num-complex", + "num-traits", + "paste", + "raw-cpuid", + "seq-macro", +] + +[[package]] +name = "gemm-c64" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbb5f2e79fefb9693d18e1066a557b4546cd334b226beadc68b11a8f9431852a" +dependencies = [ + "dyn-stack", + "gemm-common", + "num-complex", + "num-traits", + "paste", + "raw-cpuid", + "seq-macro", +] + +[[package]] +name = "gemm-common" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2e7ea062c987abcd8db95db917b4ffb4ecdfd0668471d8dc54734fdff2354e8" +dependencies = [ + "bytemuck", + "dyn-stack", + "half", + "num-complex", + "num-traits", + "once_cell", + "paste", + "pulp", + "raw-cpuid", + "rayon", + "seq-macro", + "sysctl", +] + +[[package]] +name = "gemm-f16" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca4c06b9b11952071d317604acb332e924e817bd891bec8dfb494168c7cedd4" +dependencies = [ + "dyn-stack", + "gemm-common", + "gemm-f32", + "half", + "num-complex", + "num-traits", + "paste", + "raw-cpuid", + "rayon", + "seq-macro", +] + +[[package]] +name = "gemm-f32" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9a69f51aaefbd9cf12d18faf273d3e982d9d711f60775645ed5c8047b4ae113" +dependencies = [ + "dyn-stack", + "gemm-common", + "num-complex", + "num-traits", + "paste", + "raw-cpuid", + "seq-macro", +] + +[[package]] +name = "gemm-f64" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa397a48544fadf0b81ec8741e5c0fba0043008113f71f2034def1935645d2b0" +dependencies = [ + "dyn-stack", + "gemm-common", + "num-complex", + "num-traits", + "paste", + "raw-cpuid", + "seq-macro", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gix-features" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d46a4a5c6bb5bebec9c0d18b65ada20e6517dbd7cf855b87dd4bbdce3a771b2" +dependencies = [ + "gix-hash", + "gix-trace", + "libc", +] + +[[package]] +name = "gix-fs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20e86eb040f5776a5ade092282e51cdcad398adb77d948b88d17583c2ae4e107" +dependencies = [ + "gix-features", +] + +[[package]] +name = "gix-hash" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f8cf8c2266f63e582b7eb206799b63aa5fa68ee510ad349f637dfe2d0653de0" +dependencies = [ + "faster-hex", + "thiserror", +] + +[[package]] +name = "gix-tempfile" +version = "11.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388dd29114a86ec69b28d1e26d6d63a662300ecf61ab3f4cc578f7d7dc9e7e23" +dependencies = [ + "dashmap", + "gix-fs", + "libc", + "once_cell", + "parking_lot", + "signal-hook", + "signal-hook-registry", + "tempfile", +] + +[[package]] +name = "gix-trace" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f924267408915fddcd558e3f37295cc7d6a3e50f8bd8b606cee0808c3915157e" + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glow" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gpu-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" +dependencies = [ + "bitflags 2.5.0", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "gpu-allocator" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884" +dependencies = [ + "log", + "presser", + "thiserror", + "winapi", + "windows", +] + +[[package]] +name = "gpu-descriptor" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" +dependencies = [ + "bitflags 2.5.0", + "gpu-descriptor-types", + "hashbrown 0.14.5", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bf0b36e6f090b7e1d8a4b49c0cb81c1f8376f72198c65dd3ad9ff3556b8b78c" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "bytemuck", + "cfg-if", + "crunchy", + "num-traits", + "rand", + "rand_distr", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "hassle-rs" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" +dependencies = [ + "bitflags 2.5.0", + "com", + "libc", + "libloading 0.8.3", + "thiserror", + "widestring", + "winapi", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-traits", + "png", + "qoi", + "tiff", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", +] + +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" +dependencies = [ + "rayon", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading 0.8.3", + "pkg-config", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if", + "windows-targets 0.52.5", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.5.0", + "libc", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "lru" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "matrixmultiply" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +dependencies = [ + "autocfg", + "num_cpus", + "once_cell", + "rawpointer", + "thread-tree", +] + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memmap2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +dependencies = [ + "libc", + "stable_deref_trait", +] + +[[package]] +name = "metal" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" +dependencies = [ + "bitflags 2.5.0", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", + "paste", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "naga" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e3524642f53d9af419ab5e8dd29d3ba155708267667c2f3f06c88c9e130843" +dependencies = [ + "bit-set", + "bitflags 2.5.0", + "codespan-reporting", + "hexf-parse", + "indexmap", + "log", + "num-traits", + "rustc-hash", + "spirv", + "termcolor", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "ndarray" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "rawpointer", + "rayon", +] + +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "bytemuck", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "nvml-wrapper" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd21b9f5a1cce3c3515c9ffa85f5c7443e07162dae0ccf4339bb7ca38ad3454" +dependencies = [ + "bitflags 1.3.2", + "libloading 0.7.4", + "nvml-wrapper-sys", + "static_assertions", + "thiserror", + "wrapcenum-derive", +] + +[[package]] +name = "nvml-wrapper-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c961a2ea9e91c59a69b78e69090f6f5b867bb46c0c56de9482da232437c4987e" +dependencies = [ + "libloading 0.7.4", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking_lot" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.5", +] + +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest", + "hmac", + "password-hash", + "sha2", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "png" +version = "0.17.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "pollster" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + +[[package]] +name = "proc-macro2" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" + +[[package]] +name = "pulp" +version = "0.18.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "762ad20f6b65f5a33874de3b7506d6cf6631d37fb9c0c6ee0e310d7210a167d9" +dependencies = [ + "bytemuck", + "libm", + "num-complex", + "reborrow", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r2d2" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" +dependencies = [ + "log", + "parking_lot", + "scheduled-thread-pool", +] + +[[package]] +name = "r2d2_sqlite" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc290b669d30e20751e813517bbe13662d020419c5c8818ff10b6e8bb7777f6" +dependencies = [ + "r2d2", + "rusqlite", + "uuid", +] + +[[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 = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "range-alloc" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" + +[[package]] +name = "ratatui" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5659e52e4ba6e07b2dad9f1158f578ef84a73762625ddb51536019f34d180eb" +dependencies = [ + "bitflags 2.5.0", + "cassowary", + "crossterm", + "indoc", + "itertools", + "lru", + "paste", + "stability", + "strum", + "time", + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "raw-cpuid" +version = "10.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "reborrow" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430" + +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rmp" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + +[[package]] +name = "run" +version = "0.1.0" +dependencies = [ + "bincode 1.3.3", + "serde", + "tank-ffi", +] + +[[package]] +name = "rusqlite" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a78046161564f5e7cd9008aff3b2990b3850dc8e0349119b98e8f251e099f24d" +dependencies = [ + "bitflags 2.5.0", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + +[[package]] +name = "rustls-webpki" +version = "0.102.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "safetensors" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93279b86b3de76f820a8854dd06cbc33cfa57a417b19c47f6a25280112fb1df" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "safetensors" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ced76b22c7fba1162f11a5a75d9d8405264b467a07ae0c9c29be119b9297db9" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "sanitize-filename" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ed72fbaf78e6f2d41744923916966c4fbe3d7c74e3037a8ee482f1115572603" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "scheduled-thread-pool" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "seq-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" + +[[package]] +name = "serde" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_rusqlite" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4600dac14aada464c5584d327baa164e372153309bc4c0fb1498bbfbaa5a028b" +dependencies = [ + "rusqlite", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spirv" +version = "0.3.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "stability" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd1b177894da2a2d9120208c3386066af06a488255caabc5de8ddca22dbc3ce" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.65", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "sysctl" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7dddc5f0fee506baf8b9fdb989e242f17e4b11c61dfbb0635b705217199eea" +dependencies = [ + "bitflags 2.5.0", + "byteorder", + "enum-as-inner", + "libc", + "thiserror", + "walkdir", +] + +[[package]] +name = "sysinfo" +version = "0.30.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732ffa00f53e6b2af46208fba5718d9662a421049204e156328b66791ffa15ae" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows", +] + +[[package]] +name = "systemstat" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a24aec24a9312c83999a28e3ef9db7e2afd5c64bf47725b758cdc1cafd5b0bd2" +dependencies = [ + "bytesize", + "lazy_static", + "libc", + "nom", + "time", + "winapi", +] + +[[package]] +name = "tank-ffi" +version = "0.1.0" +dependencies = [ + "bincode 1.3.3", + "burn", + "serde", +] + +[[package]] +name = "tch" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c7cb00bc2770454b515388d45be7097a3ded2eca172f3dcdb7ca4cc06c40bf1" +dependencies = [ + "half", + "lazy_static", + "libc", + "ndarray", + "rand", + "safetensors 0.3.3", + "thiserror", + "torch-sys", + "zip", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "text_placeholder" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512104f982ce6f50def5340f9d7d14cc21f7a859e9ccd251aa19d12e1345c070" +dependencies = [ + "hashbrown 0.13.2", + "serde", + "serde_json", +] + +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "thread-tree" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbd370cb847953a25954d9f63e14824a36113f8c72eecf6eccef5dc4b45d630" +dependencies = [ + "crossbeam-channel", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "torch-sys" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29e0244e5b148a31dd7fe961165037d1927754d024095c1013937532d7e73a22" +dependencies = [ + "anyhow", + "cc", + "libc", + "serde", + "serde_json", + "ureq", + "zip", +] + +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "train" +version = "0.1.0" +dependencies = [ + "bincode 1.3.3", + "burn", + "serde", + "tank-ffi", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-width" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "ureq" +version = "2.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd" +dependencies = [ + "base64", + "flate2", + "log", + "once_cell", + "rustls", + "rustls-pki-types", + "rustls-webpki", + "serde", + "serde_json", + "url", + "webpki-roots", +] + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +dependencies = [ + "getrandom", + "rand", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.65", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + +[[package]] +name = "wgpu" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd7311dbd2abcfebaabf1841a2824ed7c8be443a0f29166e5d3c6a53a762c01" +dependencies = [ + "arrayvec", + "cfg-if", + "cfg_aliases", + "js-sys", + "log", + "naga", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b94525fc99ba9e5c9a9e24764f2bc29bad0911a7446c12f446a8277369bf3a" +dependencies = [ + "arrayvec", + "bit-vec", + "bitflags 2.5.0", + "cfg_aliases", + "codespan-reporting", + "indexmap", + "log", + "naga", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "rustc-hash", + "smallvec", + "thiserror", + "web-sys", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1a4924366df7ab41a5d8546d6534f1f33231aa5b3f72b9930e300f254e39c3" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set", + "bitflags 2.5.0", + "block", + "cfg_aliases", + "core-graphics-types", + "d3d12", + "glow", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "hassle-rs", + "js-sys", + "khronos-egl", + "libc", + "libloading 0.8.3", + "log", + "metal", + "naga", + "ndk-sys", + "objc", + "once_cell", + "parking_lot", + "profiling", + "range-alloc", + "raw-window-handle", + "renderdoc-sys", + "rustc-hash", + "smallvec", + "thiserror", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "winapi", +] + +[[package]] +name = "wgpu-types" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b671ff9fb03f78b46ff176494ee1ebe7d603393f42664be55b64dc8d53969805" +dependencies = [ + "bitflags 2.5.0", + "js-sys", + "web-sys", +] + +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + +[[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-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[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" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "wrapcenum-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76ff259533532054cfbaefb115c613203c73707017459206380f03b3b3f266e" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "xml-rs" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" + +[[package]] +name = "yoke" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e71b2e4f287f467794c671e2b8f8a5f3716b3c829079a1c44740148eff07e4" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e6936f0cce458098a201c245a11bef556c6a0181129c7034d10d76d1ec3a2b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "zerofrom" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "655b0814c5c0b19ade497851070c640773304939a6c0fd5f5fb43da0696d05b7" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "aes", + "byteorder", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "flate2", + "hmac", + "pbkdf2", + "sha1", + "time", + "zstd", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.10+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] diff --git a/TankMan/.gitignore b/TankMan/.gitignore new file mode 100644 index 0000000..44adb93 --- /dev/null +++ b/TankMan/.gitignore @@ -0,0 +1,165 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.idea/ + +asset/image/mapping/image.pptx + +ml/save/ +log/ \ No newline at end of file diff --git a/TankMan/Mapping.md b/TankMan/Mapping.md new file mode 100644 index 0000000..76fa648 --- /dev/null +++ b/TankMan/Mapping.md @@ -0,0 +1,170 @@ +# 地圖製作教學 + +此文將會介紹如何使用`Tiled`這個軟體製作一個地圖,並放進[PAIA坦克大作戰](https://github.com/Jesse-Jumbo/TankMan) 中,讓我們的坦克車可以跑在自己客製化的地圖。 + +建立好的地圖除了可以直接放入[PAIA坦克大作戰](https://github.com/Jesse-Jumbo/TankMan) ,在個人環境中做使用之外,也可以分享給其他人,讓所有人使用。 + +--- +# 檔案更新 + +- [圖塊集](https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/TankManObj.png) +--- + +# 軟體安裝 + ⚙ 製作地圖需要安裝Tiled這個軟體,請大家到 [官網](https://www.mapeditor.org) 中下載適合自己電腦作業系統的版本: + +## 安裝流程: + +1. 進入到[官網](https://www.mapeditor.org)後點擊「Donload on itch.io」跳轉到下載頁面。 + ![](https://i.imgur.com/dCbcYXs.png) + + + +2. 點擊「Download Now」後將會顯示捐款浮動視窗。 + ![](https://i.imgur.com/FAk59CN.png) + + +3. 點選最上方「No thanks, just take me to the downloads」的選項後,即可看到不同作業系統適用的安裝檔。 + ![](https://i.imgur.com/VUjvlKz.png) + + +4. 選擇與自己電腦相容的安裝檔即可下載並安裝。 + ![](https://i.imgur.com/OpnUnXD.png) + + + +--- + +# 新增地圖專案 + ⚙ 這部分主要說明如何建立一個地圖檔案並儲存。 + + + +1. 開啟Tiled,建立新地圖 +第一次開啟Tiled的時候,可以在左上角看到以下截圖畫面。其中紅框內是比較常用到的功能。 +選擇「New Map」,進入到軟體中。 + ![](https://i.imgur.com/hvcCuC0.png) + + + +--- + +1. 設定地圖大小 + + 選擇建立新地圖後會跳出地圖屬性設定視窗,其中「地圖大小」的設定將會直接影響迷宮大小。 + + 將「圖塊大小」的高與寬都調整回50px,並設定好地圖大小之後就可以按下「Save As」 + ![](https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/mapping/define_map_format.jpg) + + + +--- + +1. 儲存檔案 + + 存檔時需要注意存檔類型,預設為`.tmx`,也是Tiled可以直接打開編輯的檔案格式;而坦克車使用的也是TMX檔。 + + ![](https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/mapping/save_file.jpg) + + +--- + +1. 新增圖塊集 + + 存好檔案之後就會進入到編輯頁面。 + + - 點選圖塊區域中間的「New Tileset」 + + ![](https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/mapping/new_tilsests.png) + + +- 再點擊「Browser」並打開[圖片檔](https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/TankManObj.png) 。 + ![](https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/TankManObj.png) + + +- 將圖片寬度與高度調整為50px,邊距與間距分別為0px與0px。 + ![](https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/mapping/tilsest_format.png) + + +- 成功新增圖庫集之後就可以開始編輯地圖了 + ![](https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/mapping/object_image.png) + + +--- + +# 編輯地圖 + + + ⚙ Tiled的基本編輯方式相當簡單,只需要使用滑鼠選取圖塊集的方塊,再移動到編輯區點擊方格即可。 + 也可以持續按著滑鼠左鍵拖曳繪製 +![](https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/mapping/map.png) + +--- +## 積木種類 + +圖塊集的每個格子都會有相對應的編號,其順序從1開始,由左至右、由上至下。 + +目前坦克車使用到的編號為1~5,對應到的圖塊如圖所示,這5種圖塊的功能分別為: + +1. 綠色坦克,玩家1P的起始位置,面向西方。 +2. 藍色坦克,玩家2P的起始位置,面向東方。 +3. 磚牆,遊戲中的牆壁,被擊中3次會消失。 +4. 子彈圖示,子彈補給站的起始位置,每次經過可獲得5顆子彈。 +5. WiFi圖示,油料補給站的起始位置,每次經過可獲得30點油料。 + +![](https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/mapping/image_no.png) + + +--- + +## 地圖圖塊與遊戲物件的關係 + +- 地圖圖塊的大小 = 遊戲物件的大小。 + +--- + +## 常用工具與功能列 + +- 橡皮擦 + + 在上方工具列可以找到,使用方式與圖塊集相同。 + + ![](https://i.imgur.com/8O9nkvX.png) + + +- 調整地圖大小 + + 在上方的選單選擇「地圖」→「調整地圖大小」 + + 可以調整當前地圖的長寬,並移動原先的地圖物件,在視窗中間將會出現預覽圖。 + ![](https://i.imgur.com/A1vp255.png) + + +--- + +# FAQ 與 注意事項 + +## 地圖存放路徑 +```python +Game/asset/maps/ +``` +![](https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/mapping/image_path.png) + +## 地圖檔名命名規則 + +- 檔名最後的數字(`x`)就是地圖的編號。 + - 地圖格式:map_0`x`.tmx + +--- + +## 如何更換新版圖塊集 +當更新了新版圖塊集。過去有使用過舊版的使用者有可能遇到編號不相容的問題,在此提供解決方法。 + +1. 避免在同一個檔案下使用兩個圖塊集 +2. 刪除舊版圖塊集 + +![](https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/mapping/del_image.png) + +當軟體中存在一個以上的圖塊集時編號將會存在衝突,導致載入遊戲時無法順利產生物件,因此建議使用者在同一個地圖檔案內不要使用兩個圖塊集。例如:在曾經以舊版編輯過的地圖裡直接使用新版圖塊集,可以選擇重新開新的地圖檔案套用新版的圖塊集。如果還是擔心會有混用的問題,在圖塊集的下方有垃圾桶的Icon,可以直接刪除舊的圖塊集。 + +--- \ No newline at end of file diff --git a/TankMan/README.md b/TankMan/README.md new file mode 100644 index 0000000..d41d737 --- /dev/null +++ b/TankMan/README.md @@ -0,0 +1,129 @@ +# TankMan +## 遊戲說明 +logo + + +[![TankMan](https://img.shields.io/github/v/tag/Jesse-Jumbo/TankMan)](https://github.com/Jesse-Jumbo/TankMan/tree/0.7.0) +[![Python 3.9](https://img.shields.io/badge/python-3.9-blue.svg)](https://www.python.org/downloads/release/python-390/) +[![MLGame](https://img.shields.io/badge/MLGame-10.2.5a0-.svg)](https://pypi.org/project/mlgame/10.2.5a0/) +[![pygame](https://img.shields.io/badge/pygame-2.0.1-.svg)](https://github.com/pygame/pygame/releases/tag/2.0.1) + + +坦克人(Tank Man),一款經典的雙人對戰遊戲,時間內率先擊殺對手獲勝,否則以分數高者獲勝,除了擊中對手外,破壞遊戲物件,以獲得更高積分。 + +!注意: 場上資源恢復皆須時間,先到者得,你需要這些補充品以提供前進和射擊的燃油和子彈。 + +![game.gif](https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/game.gif) +--- +## Requirements +- Python==3.9 +- mlgame==10.2.5a0 +- pytmx=3.31 +--- +## 更新說明 +- 0.6.0 版本之後,遊戲為 2~6人 團隊對抗遊戲 +- 0.7.0 版本之後,坦克和砲管的方向可以分開控制 +--- +## 遊戲簡介: +2~6位玩家進行團隊對抗賽,GreenTeam 為綠色坦克車,BlueTeam 為藍色坦克車,透過回傳遊戲指令,操控玩家與射擊砲彈,場上會有各類補給站,經過以補給該資源。 + +--- +## 畫面說明(2.x版本): +view_ex.png + +--- +# 遊戲細節: +## 啟動方式: +- 在命令行輸入命令執行。 +--- +## 遊戲參數設定 +- 在以下命令中,`.`代表執行的遊戲專案路徑,若`.`後不輸入參數,則默認使用預設值,即`game_config.json`內參數值。 +```bash +# MLGame.py +# Copy and Paste to play battle game with manual +python -m mlgame -f 120 -i ml/ml_play_manual.py -i ml/ml_play_manual.py . --green_team_num 1 --blue_team_num 1 --is_manual 1 --frame_limit 1000 + +# Copy and Paste to play battle game with AI +python -m mlgame -f 120 -i ml/ml_play.py -i ml/ml_play.py . --green_team_num 1 --blue_team_num 1 --frame_limit 1000 +``` +- `green_team_num`:選擇數字 1~3,以決定 綠隊 人數。 +- `blue_team_num`:選擇數字 1~3,以決定 藍隊 人數。 +- `is_manual`: 輸入 "1" 啟用手動模式,以讓遊戲適合手動遊玩。 +- `frame_limit`: 輸入數字 30~3000,以決定遊戲的總幀數。 +- `sound`: 輸入`on`或`off`,控制是否播放遊戲音效。 +- 如果在`mlgame`後加上`-1`,代表只執行一次遊戲。 +--- +## 遊戲操作: + +### 使用鍵盤 +- 角色移動:方向鍵控制 1P,WASD 鍵控制 2P 的移動和轉彎。 +- 角色射擊:1P 按下`M`鍵進行射擊,2P 按下`F`鍵進行射擊。 +- 遊戲畫面: 透過`I、K、J、L`來上下左右移動畫面;透過`O、U`來放大縮小畫面。 +- 隱藏遊戲資訊:按下`H`鍵,可隱藏畫面中的遊戲資訊。 +- 遊戲暫停:按下`P`鍵,可暫停遊戲(mlgame 10.2 後版本才有效)。 +- 遊戲暫停:遊戲 AI 回傳`PAUSED`指令,可暫停遊戲。 + + +### AI控制 +- 藉由遊戲資訊,在`ml`資料夾,撰寫控制遊戲角色的`.py`檔。 +- 可參考`ml_play.py`自動範例程式,撰寫自動遊玩的程式。 +- 可參考`ml_play_manual.py`手動範例程式,撰寫手動遊玩的程式。 +--- +# 遊戲玩法 +1. 團隊對抗戰 → 時間內殲滅敵對,或高分隊伍獲勝。 +## 過關條件 +1. 團隊對抗戰 + 1. 將敵隊全數擊敗。 + 2. 高過敵隊積分: + - 對方失去的生命 * `20`分。 + - 每擊中一次牆壁 * `1`分。 + - 擊破牆壁 * `5`分。 +--- +## 失敗條件 + +1. 團隊對抗戰 + 1. 生命歸零。 + 2. 時間結束,分數較敵隊低。 +--- +## 物件設定: +### **`Tank`** + +--- +1. 前進、後退速度(8 px) +2. 轉彎角度(45度) +3. 生命機會(3次) +4. 燃油(100) +5. 彈匣(10) +--- +### **`Walls`** +1. 生命次數(4) +2. 透明設定(依照生命次數決定) +--- +### **`補給站`** +1. 燃油站 + - 玩家經過補充 30點燃油,超過 100,則無效。 + - 與玩家碰撞,則隨機換位置。 + +2. 彈藥站 + - 玩家經過補充 5顆彈藥,超過 10,則無效。 + - 與玩家碰撞,則隨機換位置。 + +--- +# 地圖說明 +- 寬1000 pixel;高600 pixel +- 每格50 * 50 pixel,可放置一個物件 + +--- +# 地圖製作 +- 地圖製作教學 [Mapping.md](Mapping.md) + +--- +# image sours +- [Green Tank/Blue Tank](https://linevoom.line.me/user/_dV001P0rSN_bh8zGE0q4jmdr4Fn5d-j73cLrjTc?utm_medium=windows&utm_source=desktop&utm_campaign=Profile) +- [Bullet](https://linevoom.line.me/user/_dV001P0rSN_bh8zGE0q4jmdr4Fn5d-j73cLrjTc?utm_medium=windows&utm_source=desktop&utm_campaign=Profile) +- [Hourglass](https://opengameart.org/content/animated-hourglass) +- [Other Object](https://opengameart.org/content/simple-shooter-icons) + +# sound sours +- [BGM](https://opengameart.org/content/commando-team-action-loop-cut) +- [SHOOT](https://opengameart.org/content/random-low-quality-sfx) diff --git a/TankMan/__init__.py b/TankMan/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/TankMan/asset/image/1P.png b/TankMan/asset/image/1P.png new file mode 100644 index 0000000..cdceba7 Binary files /dev/null and b/TankMan/asset/image/1P.png differ diff --git a/TankMan/asset/image/1P.svg b/TankMan/asset/image/1P.svg new file mode 100644 index 0000000..249ef50 --- /dev/null +++ b/TankMan/asset/image/1P.svg @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/1P_body.png b/TankMan/asset/image/1P_body.png new file mode 100644 index 0000000..4605a68 Binary files /dev/null and b/TankMan/asset/image/1P_body.png differ diff --git a/TankMan/asset/image/1P_body.svg b/TankMan/asset/image/1P_body.svg new file mode 100644 index 0000000..9182ca7 --- /dev/null +++ b/TankMan/asset/image/1P_body.svg @@ -0,0 +1,150 @@ + + + + + + + TankMan_1_V2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/1P_gun.png b/TankMan/asset/image/1P_gun.png new file mode 100644 index 0000000..bbf83ae Binary files /dev/null and b/TankMan/asset/image/1P_gun.png differ diff --git a/TankMan/asset/image/1P_gun.svg b/TankMan/asset/image/1P_gun.svg new file mode 100644 index 0000000..ecedcc5 --- /dev/null +++ b/TankMan/asset/image/1P_gun.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + TankMan_1_V2 + + + + + + + + diff --git a/TankMan/asset/image/2P.png b/TankMan/asset/image/2P.png new file mode 100644 index 0000000..d24571c Binary files /dev/null and b/TankMan/asset/image/2P.png differ diff --git a/TankMan/asset/image/2P.svg b/TankMan/asset/image/2P.svg new file mode 100644 index 0000000..4cdddcd --- /dev/null +++ b/TankMan/asset/image/2P.svg @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/2P_body.png b/TankMan/asset/image/2P_body.png new file mode 100644 index 0000000..26b978a Binary files /dev/null and b/TankMan/asset/image/2P_body.png differ diff --git a/TankMan/asset/image/2P_body.svg b/TankMan/asset/image/2P_body.svg new file mode 100644 index 0000000..e732987 --- /dev/null +++ b/TankMan/asset/image/2P_body.svg @@ -0,0 +1,150 @@ + + + + + + + TankMan_2_V2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/2P_gun.png b/TankMan/asset/image/2P_gun.png new file mode 100644 index 0000000..c0c1ad2 Binary files /dev/null and b/TankMan/asset/image/2P_gun.png differ diff --git a/TankMan/asset/image/2P_gun.svg b/TankMan/asset/image/2P_gun.svg new file mode 100644 index 0000000..696327f --- /dev/null +++ b/TankMan/asset/image/2P_gun.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + TankMan_2_V2 + + + + + + + + diff --git a/TankMan/asset/image/TankMan.svg b/TankMan/asset/image/TankMan.svg new file mode 100644 index 0000000..27e3854 --- /dev/null +++ b/TankMan/asset/image/TankMan.svg @@ -0,0 +1 @@ +car \ No newline at end of file diff --git a/TankMan/asset/image/TankManObj.png b/TankMan/asset/image/TankManObj.png new file mode 100644 index 0000000..945a93a Binary files /dev/null and b/TankMan/asset/image/TankManObj.png differ diff --git a/TankMan/asset/image/TankMan_obj.svg b/TankMan/asset/image/TankMan_obj.svg new file mode 100644 index 0000000..446ce99 --- /dev/null +++ b/TankMan/asset/image/TankMan_obj.svg @@ -0,0 +1,1184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/border.png b/TankMan/asset/image/border.png new file mode 100644 index 0000000..fe91691 Binary files /dev/null and b/TankMan/asset/image/border.png differ diff --git a/TankMan/asset/image/border.svg b/TankMan/asset/image/border.svg new file mode 100644 index 0000000..92252a2 --- /dev/null +++ b/TankMan/asset/image/border.svg @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/bullets.png b/TankMan/asset/image/bullets.png new file mode 100644 index 0000000..b49e98d Binary files /dev/null and b/TankMan/asset/image/bullets.png differ diff --git a/TankMan/asset/image/bullets.svg b/TankMan/asset/image/bullets.svg new file mode 100644 index 0000000..bb03710 --- /dev/null +++ b/TankMan/asset/image/bullets.svg @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/game.gif b/TankMan/asset/image/game.gif new file mode 100644 index 0000000..7f9dd5c Binary files /dev/null and b/TankMan/asset/image/game.gif differ diff --git a/TankMan/asset/image/grass_0.png b/TankMan/asset/image/grass_0.png new file mode 100644 index 0000000..a1b03e4 Binary files /dev/null and b/TankMan/asset/image/grass_0.png differ diff --git a/TankMan/asset/image/grass_1.png b/TankMan/asset/image/grass_1.png new file mode 100644 index 0000000..91ce067 Binary files /dev/null and b/TankMan/asset/image/grass_1.png differ diff --git a/TankMan/asset/image/grass_2.png b/TankMan/asset/image/grass_2.png new file mode 100644 index 0000000..bbcbbdd Binary files /dev/null and b/TankMan/asset/image/grass_2.png differ diff --git a/TankMan/asset/image/hourglass.png b/TankMan/asset/image/hourglass.png new file mode 100644 index 0000000..8dde1e1 Binary files /dev/null and b/TankMan/asset/image/hourglass.png differ diff --git a/TankMan/asset/image/hourglass_0.png b/TankMan/asset/image/hourglass_0.png new file mode 100644 index 0000000..11ddf59 Binary files /dev/null and b/TankMan/asset/image/hourglass_0.png differ diff --git a/TankMan/asset/image/hourglass_1.png b/TankMan/asset/image/hourglass_1.png new file mode 100644 index 0000000..049a86c Binary files /dev/null and b/TankMan/asset/image/hourglass_1.png differ diff --git a/TankMan/asset/image/hourglass_10.png b/TankMan/asset/image/hourglass_10.png new file mode 100644 index 0000000..1990d7c Binary files /dev/null and b/TankMan/asset/image/hourglass_10.png differ diff --git a/TankMan/asset/image/hourglass_11.png b/TankMan/asset/image/hourglass_11.png new file mode 100644 index 0000000..d5a3427 Binary files /dev/null and b/TankMan/asset/image/hourglass_11.png differ diff --git a/TankMan/asset/image/hourglass_12.png b/TankMan/asset/image/hourglass_12.png new file mode 100644 index 0000000..a8c5904 Binary files /dev/null and b/TankMan/asset/image/hourglass_12.png differ diff --git a/TankMan/asset/image/hourglass_13.png b/TankMan/asset/image/hourglass_13.png new file mode 100644 index 0000000..0eca37d Binary files /dev/null and b/TankMan/asset/image/hourglass_13.png differ diff --git a/TankMan/asset/image/hourglass_14.png b/TankMan/asset/image/hourglass_14.png new file mode 100644 index 0000000..b63624f Binary files /dev/null and b/TankMan/asset/image/hourglass_14.png differ diff --git a/TankMan/asset/image/hourglass_2.png b/TankMan/asset/image/hourglass_2.png new file mode 100644 index 0000000..8f80097 Binary files /dev/null and b/TankMan/asset/image/hourglass_2.png differ diff --git a/TankMan/asset/image/hourglass_3.png b/TankMan/asset/image/hourglass_3.png new file mode 100644 index 0000000..172e6db Binary files /dev/null and b/TankMan/asset/image/hourglass_3.png differ diff --git a/TankMan/asset/image/hourglass_4.png b/TankMan/asset/image/hourglass_4.png new file mode 100644 index 0000000..ae265fa Binary files /dev/null and b/TankMan/asset/image/hourglass_4.png differ diff --git a/TankMan/asset/image/hourglass_5.png b/TankMan/asset/image/hourglass_5.png new file mode 100644 index 0000000..ff29339 Binary files /dev/null and b/TankMan/asset/image/hourglass_5.png differ diff --git a/TankMan/asset/image/hourglass_6.png b/TankMan/asset/image/hourglass_6.png new file mode 100644 index 0000000..c978d37 Binary files /dev/null and b/TankMan/asset/image/hourglass_6.png differ diff --git a/TankMan/asset/image/hourglass_7.png b/TankMan/asset/image/hourglass_7.png new file mode 100644 index 0000000..3902a87 Binary files /dev/null and b/TankMan/asset/image/hourglass_7.png differ diff --git a/TankMan/asset/image/hourglass_8.png b/TankMan/asset/image/hourglass_8.png new file mode 100644 index 0000000..76b9dfb Binary files /dev/null and b/TankMan/asset/image/hourglass_8.png differ diff --git a/TankMan/asset/image/hourglass_9.png b/TankMan/asset/image/hourglass_9.png new file mode 100644 index 0000000..b72e8cc Binary files /dev/null and b/TankMan/asset/image/hourglass_9.png differ diff --git a/TankMan/asset/image/logo.png b/TankMan/asset/image/logo.png new file mode 100644 index 0000000..8d707f3 Binary files /dev/null and b/TankMan/asset/image/logo.png differ diff --git a/TankMan/asset/image/mapping/define_map_format.jpg b/TankMan/asset/image/mapping/define_map_format.jpg new file mode 100644 index 0000000..4b6f631 Binary files /dev/null and b/TankMan/asset/image/mapping/define_map_format.jpg differ diff --git a/TankMan/asset/image/mapping/del_image.png b/TankMan/asset/image/mapping/del_image.png new file mode 100644 index 0000000..6e05348 Binary files /dev/null and b/TankMan/asset/image/mapping/del_image.png differ diff --git a/TankMan/asset/image/mapping/image_no.png b/TankMan/asset/image/mapping/image_no.png new file mode 100644 index 0000000..b48e40e Binary files /dev/null and b/TankMan/asset/image/mapping/image_no.png differ diff --git a/TankMan/asset/image/mapping/image_path.png b/TankMan/asset/image/mapping/image_path.png new file mode 100644 index 0000000..e2798e3 Binary files /dev/null and b/TankMan/asset/image/mapping/image_path.png differ diff --git a/TankMan/asset/image/mapping/map.png b/TankMan/asset/image/mapping/map.png new file mode 100644 index 0000000..0139a7b Binary files /dev/null and b/TankMan/asset/image/mapping/map.png differ diff --git a/TankMan/asset/image/mapping/new_tilsests.png b/TankMan/asset/image/mapping/new_tilsests.png new file mode 100644 index 0000000..6e99f2d Binary files /dev/null and b/TankMan/asset/image/mapping/new_tilsests.png differ diff --git a/TankMan/asset/image/mapping/object_image.png b/TankMan/asset/image/mapping/object_image.png new file mode 100644 index 0000000..ec58eb8 Binary files /dev/null and b/TankMan/asset/image/mapping/object_image.png differ diff --git a/TankMan/asset/image/mapping/save_file.jpg b/TankMan/asset/image/mapping/save_file.jpg new file mode 100644 index 0000000..425ae6f Binary files /dev/null and b/TankMan/asset/image/mapping/save_file.jpg differ diff --git a/TankMan/asset/image/mapping/tilsest_format.png b/TankMan/asset/image/mapping/tilsest_format.png new file mode 100644 index 0000000..190fed0 Binary files /dev/null and b/TankMan/asset/image/mapping/tilsest_format.png differ diff --git a/TankMan/asset/image/not_used.svg b/TankMan/asset/image/not_used.svg new file mode 100644 index 0000000..2f99724 --- /dev/null +++ b/TankMan/asset/image/not_used.svg @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/oil.png b/TankMan/asset/image/oil.png new file mode 100644 index 0000000..95a3563 Binary files /dev/null and b/TankMan/asset/image/oil.png differ diff --git a/TankMan/asset/image/oil.svg b/TankMan/asset/image/oil.svg new file mode 100644 index 0000000..fbf0623 --- /dev/null +++ b/TankMan/asset/image/oil.svg @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/qubodup_ringicons.svg b/TankMan/asset/image/qubodup_ringicons.svg new file mode 100644 index 0000000..6cba1d1 --- /dev/null +++ b/TankMan/asset/image/qubodup_ringicons.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/team_a_bullet.png b/TankMan/asset/image/team_a_bullet.png new file mode 100644 index 0000000..a61a7fd Binary files /dev/null and b/TankMan/asset/image/team_a_bullet.png differ diff --git a/TankMan/asset/image/team_a_bullet.svg b/TankMan/asset/image/team_a_bullet.svg new file mode 100644 index 0000000..8100912 --- /dev/null +++ b/TankMan/asset/image/team_a_bullet.svg @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/team_a_lives_1.png b/TankMan/asset/image/team_a_lives_1.png new file mode 100644 index 0000000..87b97e5 Binary files /dev/null and b/TankMan/asset/image/team_a_lives_1.png differ diff --git a/TankMan/asset/image/team_a_lives_1.svg b/TankMan/asset/image/team_a_lives_1.svg new file mode 100644 index 0000000..e7a4e23 --- /dev/null +++ b/TankMan/asset/image/team_a_lives_1.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/team_a_lives_2.png b/TankMan/asset/image/team_a_lives_2.png new file mode 100644 index 0000000..4ef3e30 Binary files /dev/null and b/TankMan/asset/image/team_a_lives_2.png differ diff --git a/TankMan/asset/image/team_a_lives_2.svg b/TankMan/asset/image/team_a_lives_2.svg new file mode 100644 index 0000000..e1bc6cc --- /dev/null +++ b/TankMan/asset/image/team_a_lives_2.svg @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/team_a_lives_3.png b/TankMan/asset/image/team_a_lives_3.png new file mode 100644 index 0000000..2155ecc Binary files /dev/null and b/TankMan/asset/image/team_a_lives_3.png differ diff --git a/TankMan/asset/image/team_a_lives_3.svg b/TankMan/asset/image/team_a_lives_3.svg new file mode 100644 index 0000000..d7ca9ca --- /dev/null +++ b/TankMan/asset/image/team_a_lives_3.svg @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/team_b_bullet.png b/TankMan/asset/image/team_b_bullet.png new file mode 100644 index 0000000..fdd0970 Binary files /dev/null and b/TankMan/asset/image/team_b_bullet.png differ diff --git a/TankMan/asset/image/team_b_bullet.svg b/TankMan/asset/image/team_b_bullet.svg new file mode 100644 index 0000000..1e0fe61 --- /dev/null +++ b/TankMan/asset/image/team_b_bullet.svg @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/team_b_lives_1.png b/TankMan/asset/image/team_b_lives_1.png new file mode 100644 index 0000000..021743e Binary files /dev/null and b/TankMan/asset/image/team_b_lives_1.png differ diff --git a/TankMan/asset/image/team_b_lives_1.svg b/TankMan/asset/image/team_b_lives_1.svg new file mode 100644 index 0000000..9cad6d9 --- /dev/null +++ b/TankMan/asset/image/team_b_lives_1.svg @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/team_b_lives_2.png b/TankMan/asset/image/team_b_lives_2.png new file mode 100644 index 0000000..db1aa9f Binary files /dev/null and b/TankMan/asset/image/team_b_lives_2.png differ diff --git a/TankMan/asset/image/team_b_lives_2.svg b/TankMan/asset/image/team_b_lives_2.svg new file mode 100644 index 0000000..b6addbb --- /dev/null +++ b/TankMan/asset/image/team_b_lives_2.svg @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/team_b_lives_3.png b/TankMan/asset/image/team_b_lives_3.png new file mode 100644 index 0000000..88ec74b Binary files /dev/null and b/TankMan/asset/image/team_b_lives_3.png differ diff --git a/TankMan/asset/image/team_b_lives_3.svg b/TankMan/asset/image/team_b_lives_3.svg new file mode 100644 index 0000000..0a011c2 --- /dev/null +++ b/TankMan/asset/image/team_b_lives_3.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/TankMan/asset/image/view_ex.png b/TankMan/asset/image/view_ex.png new file mode 100644 index 0000000..945f3cc Binary files /dev/null and b/TankMan/asset/image/view_ex.png differ diff --git a/TankMan/asset/image/wall.png b/TankMan/asset/image/wall.png new file mode 100644 index 0000000..0eba8d3 Binary files /dev/null and b/TankMan/asset/image/wall.png differ diff --git a/TankMan/asset/image/wall_1.png b/TankMan/asset/image/wall_1.png new file mode 100644 index 0000000..2c2b250 Binary files /dev/null and b/TankMan/asset/image/wall_1.png differ diff --git a/TankMan/asset/image/wall_2.png b/TankMan/asset/image/wall_2.png new file mode 100644 index 0000000..c9a2e41 Binary files /dev/null and b/TankMan/asset/image/wall_2.png differ diff --git a/TankMan/asset/image/wall_3.png b/TankMan/asset/image/wall_3.png new file mode 100644 index 0000000..0eba8d3 Binary files /dev/null and b/TankMan/asset/image/wall_3.png differ diff --git a/TankMan/asset/maps/map_1_v_1.tmx b/TankMan/asset/maps/map_1_v_1.tmx new file mode 100644 index 0000000..0bf0636 --- /dev/null +++ b/TankMan/asset/maps/map_1_v_1.tmx @@ -0,0 +1,22 @@ + + + + + + + +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,5,0,0,0,0,0,0,0,0,0,4,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3, +3,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,4,0,0,0,0,0,0,0,0,0,5,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 + + + diff --git a/TankMan/asset/maps/map_1_v_2.tmx b/TankMan/asset/maps/map_1_v_2.tmx new file mode 100644 index 0000000..83e3162 --- /dev/null +++ b/TankMan/asset/maps/map_1_v_2.tmx @@ -0,0 +1,22 @@ + + + + + + + +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,2,0,0,5,0,0,0,3,0,0,0,0,0,4,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,1,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,4,0,0,0,0,0,3,0,0,0,5,0,0,0,0,3, +3,0,2,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 + + + diff --git a/TankMan/asset/maps/map_1_v_5.tmx b/TankMan/asset/maps/map_1_v_5.tmx new file mode 100644 index 0000000..fc830ae --- /dev/null +++ b/TankMan/asset/maps/map_1_v_5.tmx @@ -0,0 +1,22 @@ + + + + + + + +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,0,2,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,2,0,0,5,0,0,0,3,0,0,0,0,0,4,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,2,0,0,0,0,0,0,3,0,0,0,0,0,0,0,1,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,2,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,4,0,0,0,0,0,3,0,0,0,5,0,0,0,0,3, +3,0,2,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 + + + diff --git a/TankMan/asset/maps/map_2_v_1.tmx b/TankMan/asset/maps/map_2_v_1.tmx new file mode 100644 index 0000000..b7101b0 --- /dev/null +++ b/TankMan/asset/maps/map_2_v_1.tmx @@ -0,0 +1,22 @@ + + + + + + + +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,1,0,3, +3,0,0,0,0,5,0,0,0,3,0,0,0,0,0,4,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,2,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,4,0,0,0,0,0,3,0,0,0,5,0,0,1,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 + + + diff --git a/TankMan/asset/maps/map_2_v_2.tmx b/TankMan/asset/maps/map_2_v_2.tmx new file mode 100644 index 0000000..ce030b2 --- /dev/null +++ b/TankMan/asset/maps/map_2_v_2.tmx @@ -0,0 +1,22 @@ + + + + + + + +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,1,0,3, +3,0,2,0,0,5,0,0,0,3,0,0,0,0,0,4,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,4,0,0,0,0,0,3,0,0,0,5,0,0,1,0,3, +3,0,2,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 + + + diff --git a/TankMan/asset/maps/map_2_v_3.tmx b/TankMan/asset/maps/map_2_v_3.tmx new file mode 100644 index 0000000..dba563b --- /dev/null +++ b/TankMan/asset/maps/map_2_v_3.tmx @@ -0,0 +1,22 @@ + + + + + + + +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,1,0,3, +3,0,2,0,0,5,0,0,0,3,0,0,0,0,0,4,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,2,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,4,0,0,0,0,0,3,0,0,0,5,0,0,1,0,3, +3,0,2,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 + + + diff --git a/TankMan/asset/maps/map_3_v_2.tmx b/TankMan/asset/maps/map_3_v_2.tmx new file mode 100644 index 0000000..3fe8591 --- /dev/null +++ b/TankMan/asset/maps/map_3_v_2.tmx @@ -0,0 +1,22 @@ + + + + + + + +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,1,0,3, +3,0,2,0,0,5,0,0,0,3,0,0,0,0,0,4,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,1,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,4,0,0,0,0,0,3,0,0,0,5,0,0,1,0,3, +3,0,2,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 + + + diff --git a/TankMan/asset/maps/map_3_v_3.tmx b/TankMan/asset/maps/map_3_v_3.tmx new file mode 100644 index 0000000..5ec4a1b --- /dev/null +++ b/TankMan/asset/maps/map_3_v_3.tmx @@ -0,0 +1,35 @@ + + + + + + + +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,2,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,4,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,3, +3,0,0,0,0,0,0,5,0,0,0,3,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,3,0,4,0,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,2,0,3,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,3,3,5,0,0,0,0,0,0,3,0,0,5,0,0,0,3,3,0,0,0,0,5,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,0,4,0,3,0,0,0,0,0,0,3,3,0,1,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,4,0,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,3, +3,0,4,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, +3,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 + + + + \ No newline at end of file diff --git a/TankMan/asset/sound/BGM.ogg b/TankMan/asset/sound/BGM.ogg new file mode 100644 index 0000000..a42d843 Binary files /dev/null and b/TankMan/asset/sound/BGM.ogg differ diff --git a/TankMan/asset/sound/shoot.wav b/TankMan/asset/sound/shoot.wav new file mode 100644 index 0000000..84fd6c0 Binary files /dev/null and b/TankMan/asset/sound/shoot.wav differ diff --git a/TankMan/asset/sound/touch.wav b/TankMan/asset/sound/touch.wav new file mode 100644 index 0000000..a720814 Binary files /dev/null and b/TankMan/asset/sound/touch.wav differ diff --git a/TankMan/blockly.json b/TankMan/blockly.json new file mode 100644 index 0000000..2dda426 --- /dev/null +++ b/TankMan/blockly.json @@ -0,0 +1,61 @@ +{ + "INIT_INFO": [ + ["ai_name", "player number", "玩家編號"] + ], + "PLAYER_STATUS":[ + ["1P", "1P", "1P"], + ["2P", "2P", "2P"], + ["3P", "3P", "3P"], + ["4P", "4P", "4P"], + ["5P", "5P", "5P"], + ["6P", "6P", "6P"] + ], + "GAME_STATUS": [ + ["GAME_ALIVE", "alive", "存活"], + ["GAME_DRAW", "draw", "平手"], + ["GREEN_TEAM_WIN", "green team win", "綠隊獲勝"], + ["BLUE_TEAM_WIN", "blue team win", "籃隊獲勝"] + ], + "SCENE_INFO": [ + ["scene_info['id']", "player number", "玩家編號"], + ["scene_info['x']", "x coordinate of player", "玩家的 x 座標"], + ["scene_info['y']", "y coordinate of player", "玩家的 y 座標"], + ["scene_info['speed']", "player speed", "玩家速度"], + ["scene_info['score']", "score of player", "玩家分數"], + ["scene_info['power']", "power of player", "玩家子彈數"], + ["scene_info['oil']", "oil of player", "玩家油量"], + ["scene_info['lives']", "lives of player", "玩家的生命次數"], + ["scene_info['angle']", "angle of player", "玩家的面朝角度"], + ["scene_info['used_frame']", "# frame", "# 幀數"], + ["scene_info['status']", "game status", "遊戲狀態"], + ["scene_info['competitor_info']", "coordinate of all competitor", "所有對手的所有資訊"], + ["scene_info['walls_info']", "coordinate of all walls", "所有牆的所有資訊"], + ["scene_info['bullet_stations_info']", "information of all walls", "所有彈藥庫的所有資訊"], + ["scene_info['oil_stations_info']", "information of all walls", "所有加油站的所有資訊"] + ], + "CONSTANT": [ + [0, "left boundary", "左邊界"], + [1000, "right boundary", "右邊界"], + [0, "top boundary", "上邊界"], + [600, "bottom boundary", "下邊界"], + [50, "obj width", "物件寬度"], + [50, "obj height", "物件高度"] + ], + "ACTION": [ + ["['FORWARD']", "forward", "前進"], + ["['BACKWARD']", "backward", "後退"], + ["['TURN_LEFT']", "turn left", "左轉"], + ["['TURN_RIGHT']", "turn right", "右轉"], + ["['AIM_LEFT']", "aim left", "砲管左轉"], + ["['AIM_RIGHT']", "aim right", "砲管右轉"], + ["['SHOOT']","shoot", "射擊"], + ["['FORWARD', 'SHOOT']", "forward shoot", "前進並射擊"], + ["['BACKWARD', 'SHOOT']", "backward shoot", "後退並射擊"], + ["['TURN_LEFT', 'SHOOT']", "turn left shoot", "左轉並射擊"], + ["['TURN_RIGHT', 'SHOOT']", "turn right shoot", "右轉並射擊"], + ["['TURN_LEFT', 'AIM_LEFT', 'SHOOT']", "turn left and aim left shoot", "左轉並砲管左轉射擊"], + ["['TURN_RIGHT', 'AIM_RIGHT', 'SHOOT']", "turn right and aim right shoot", "右轉並砲管右轉射擊"], + ["['NONE']","doing nothing", "不動作"], + ["RESET", "reset", "重置遊戲"] + ] +} \ No newline at end of file diff --git a/TankMan/command.txt b/TankMan/command.txt new file mode 100644 index 0000000..b39edc5 --- /dev/null +++ b/TankMan/command.txt @@ -0,0 +1 @@ +python -m mlgame -f 10 -i ml/ml_play_manual.py -i ml/ml_play_manual.py -i ml/ml_play_manual.py -i ml/ml_play_manual.py -i ml/ml_play_manual.py -i ml/ml_play_manual.py . --green_team_num 3 --blue_team_num 3 --is_manual 1 --frame_limit 1000 \ No newline at end of file diff --git a/TankMan/config.py b/TankMan/config.py new file mode 100644 index 0000000..1b7f709 --- /dev/null +++ b/TankMan/config.py @@ -0,0 +1,10 @@ +import sys +from os import path + +sys.path.append(path.dirname(__file__)) +from src.Game import Game + +GAME_SETUP = { + "game": Game, +} + diff --git a/TankMan/contest.py b/TankMan/contest.py new file mode 100644 index 0000000..c1e3425 --- /dev/null +++ b/TankMan/contest.py @@ -0,0 +1,137 @@ +import pygame +from mlgame.game.generic import quit_or_esc +from src.Game import Game +from tqdm import tqdm +import argparse +import importlib + + + +class Contest(): + """ + This class manages a 3 vs 3 game contest. + + Parameters + ---------- + player : list + The list of players. + total_game : int + The total number of games. + frame : int + The frame of the game. + sound : str + The sound of the game. + is_manual : bool + The manual mode of the game. + + Returns + ------- + dict + The result of the game. + """ + def __init__(self, player: list, total_game: int, frame: int, + sound: str, is_manual: bool): + # initialize player + self.player1 = player[0] + self.player2 = player[1] + self.player3 = player[2] + self.player4 = player[3] + self.player5 = player[4] + self.player6 = player[5] + + # initialize game + self.total_game = total_game + self.frame = frame + self.sound = sound + self.is_manual = is_manual + + self.user_num = 6 + self.green_team_num = 3 + self.blue_team_num = 3 + + # initialize game times + self.game_times = 0 + self.green_team_win = 0 + self.blue_team_win = 0 + + def run(self): + with tqdm(total=self.total_game, unit="round") as pbar: + pbar.set_description("Playing") + print() + for _ in range(self.total_game): + # initialize game every round + game = Game(self.user_num, self.green_team_num, + self.blue_team_num, self.is_manual, self.frame, self.sound) + scene_init_info_dict = game.get_scene_init_data() + frame_count = 0 + + # update game + while game.is_running() and not quit_or_esc(): + game.update({ + "1P": self.player1.update(game.get_data_from_game_to_player()['1P'], []), + "2P": self.player2.update(game.get_data_from_game_to_player()['2P'], []), + "3P": self.player3.update(game.get_data_from_game_to_player()['3P'], []), + "4P": self.player4.update(game.get_data_from_game_to_player()['4P'], []), + "5P": self.player5.update(game.get_data_from_game_to_player()['5P'], []), + "6P": self.player6.update(game.get_data_from_game_to_player()['6P'], []) + }) + frame_count += 1 + + # reset player + self.player1.reset() + self.player2.reset() + self.player3.reset() + self.player4.reset() + self.player5.reset() + self.player6.reset() + self.game_times += 1 + + # get game result + game_result = game.get_game_result() + if game_result['attachment'][0]["status"] == "GREEN_TEAM_WIN": + self.green_team_win += 1 + else: + self.blue_team_win += 1 + + # update progress bar + pbar.postfix = f"green_team win: {self.green_team_win} | blue_team win: {self.blue_team_win}" + pbar.update(1) + # print() + if self.green_team_win > self.total_game/2 or self.blue_team_win > self.total_game/2: + break + + + print(f"Game times: {self.game_times} | green_team win: {self.green_team_win} | blue_team win: {self.blue_team_win}") + pygame.quit() + return {"green_team_win":self.green_team_win, "blue_team_win":self.blue_team_win} + +def import_player(group_number, player_number): + module_name = f"ml.Group_{group_number}.ml_play_{player_number}" + module = importlib.import_module(module_name) + return getattr(module, f"MLPlay") + +if __name__ == '__main__': + # Set configuration + sound = "off" + total_game = 9 + frame = 2500 + is_manual = False + + parser = argparse.ArgumentParser() + parser.add_argument("--green_team", type=str, required=True, help="The folder of the green team") + parser.add_argument("--blue_team", type=str, required=True, help="The folder of the blue team") + args = parser.parse_args() + print(args) + player1 = import_player(1, 1) + + + players = [ import_player(args.green_team, 1)('1P', {'sound': sound}), + import_player(args.green_team, 2)('2P', {'sound': sound}), + import_player(args.green_team, 3)('3P', {'sound': sound}), + import_player(args.blue_team, 1)('4P', {'sound': sound}), + import_player(args.blue_team, 2)('5P', {'sound': sound}), + import_player(args.blue_team, 3)('6P', {'sound': sound})] + + contest = Contest(players, total_game , frame, sound, is_manual) + contest.run() + \ No newline at end of file diff --git a/TankMan/doc/ClassDiagram.mdj b/TankMan/doc/ClassDiagram.mdj new file mode 100644 index 0000000..1470809 --- /dev/null +++ b/TankMan/doc/ClassDiagram.mdj @@ -0,0 +1,9792 @@ +{ + "_type": "Project", + "_id": "AAAAAAFF+h6SjaM2Hec=", + "name": "Untitled", + "ownedElements": [ + { + "_type": "UMLModel", + "_id": "AAAAAAFF+qBWK6M3Z8Y=", + "_parent": { + "$ref": "AAAAAAFF+h6SjaM2Hec=" + }, + "name": "Model", + "ownedElements": [ + { + "_type": "UMLClassDiagram", + "_id": "AAAAAAFF+qBtyKM79qY=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Main", + "defaultDiagram": true, + "ownedViews": [ + { + "_type": "UMLClassView", + "_id": "AAAAAAGAXjxqhKVg3/0=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGAXjxqhKVhfuo=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVg3/0=" + }, + "model": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGAXjxqhKViQ6o=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVhfuo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": -240, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAXjxqhKVjFeI=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVhfuo=" + }, + "font": "Arial;13;1", + "left": 365, + "top": 103, + "width": 394.18310546875, + "height": 13, + "text": "GameMode" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAXjxqhKVkrw8=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVhfuo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": -240, + "width": 80.5009765625, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAXjxqhKVlyhY=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVhfuo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": -240, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 360, + "top": 96, + "width": 404.18310546875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGAXjxqhKViQ6o=" + }, + "nameLabel": { + "$ref": "AAAAAAGAXjxqhKVjFeI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGAXjxqhKVkrw8=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAXjxqhKVlyhY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGAXjxqhKVmFgA=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVg3/0=" + }, + "model": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk0r8q6XP1/0=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAk0r8lqXMu2M=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 126, + "width": 394.18310546875, + "height": 13, + "text": "+all_sprites: Group", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAXj2LdaWRPC8=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAXj2LaKWObGk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 357, + "top": 229, + "width": 394.18310546875, + "height": 13, + "text": "+bullets: Group", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk3nQ16Yp4OE=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAk3nQ0KYmHrg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 357, + "top": 244, + "width": 394.18310546875, + "height": 13, + "text": "+walls: Group", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk3yvcaZFFZ8=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAk3yvZqZCZa4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 357, + "top": 244, + "width": 394.18310546875, + "height": 13, + "text": "+mobs: Group", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk28mHqYSbJo=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAk28mGKYPh40=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 357, + "top": 244, + "width": 394.18310546875, + "height": 13, + "text": "+player_1P: Sprite", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk2WvzqYLrL4=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAk2WvwaYITAc=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 141, + "width": 394.18310546875, + "height": 13, + "text": "+is_paused: Bool", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk3fk/qYZjoY=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAk3fk+KYW84M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 357, + "top": 304, + "width": 386.953125, + "height": 13, + "text": "+is_playing: Bool", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk3hGl6YhMEk=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAk3hGkKYe19M=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 156, + "width": 394.18310546875, + "height": 13, + "text": "+is_sound: Bool", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk2Un9aYEJdY=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAk2Un6KYBvzo=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 171, + "width": 394.18310546875, + "height": 13, + "text": "+used_frame: Int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAmBTs97difk8=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAmBTs57dfR+A=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 186, + "width": 394.18310546875, + "height": 13, + "text": "+frame_limit: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk3qQWaYwdgE=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAk3qQUqYtB2U=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 201, + "width": 394.18310546875, + "height": 13, + "text": "+window: pygame.Surface", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl1t4HUO/dCI=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAl1t4D0O8V40=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 216, + "width": 394.18310546875, + "height": 13, + "text": "+map: TiledMap", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAmAyRz1DW6g8=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAmAyRvVDTY88=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 231, + "width": 394.18310546875, + "height": 13, + "text": "+state: Str", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAmAzqtFQs0MI=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "model": { + "$ref": "AAAAAAGAmAzqn1QpDMk=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 246, + "width": 394.18310546875, + "height": 13, + "text": "+status: str", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 360, + "top": 121, + "width": 404.18310546875, + "height": 143 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGAXjxqhKVnmdQ=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVg3/0=" + }, + "model": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk15L26XXJXg=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVnmdQ=" + }, + "model": { + "$ref": "AAAAAAGAk15Ly6XULl4=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 269, + "width": 394.18310546875, + "height": 13, + "text": "-__init__(map_path: Str, time_limit: Int, sound: Bool): None", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk171BaXfoSI=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVnmdQ=" + }, + "model": { + "$ref": "AAAAAAGAk1709KXc5+4=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 284, + "width": 394.18310546875, + "height": 13, + "text": "+get_result(): Dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk18966XnW1M=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVnmdQ=" + }, + "model": { + "$ref": "AAAAAAGAk1894KXkSJ8=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 299, + "width": 394.18310546875, + "height": 13, + "text": "+updata(command: Dict): None", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk2Bn9qXwSdI=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVnmdQ=" + }, + "model": { + "$ref": "AAAAAAGAk2Bn7qXt7o8=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 314, + "width": 394.18310546875, + "height": 13, + "text": "+check_events(): None", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk2DZO6X3pOY=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVnmdQ=" + }, + "model": { + "$ref": "AAAAAAGAk2DZMqX0aQQ=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 329, + "width": 394.18310546875, + "height": 13, + "text": "+check_collisions(): None", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAmBa4nrpzsm0=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVnmdQ=" + }, + "model": { + "$ref": "AAAAAAGAmBa4jbpw4xo=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 344, + "width": 394.18310546875, + "height": 13, + "text": "+reset(): tuple", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAtcd4HZ059lE=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVnmdQ=" + }, + "model": { + "$ref": "AAAAAAGAtcd3+p02Ti8=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 359, + "width": 394.18310546875, + "height": 13, + "text": "+draw_sprite_data()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAtcf9VqFpfBw=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVnmdQ=" + }, + "model": { + "$ref": "AAAAAAGAtcf9QKFmM8o=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 374, + "width": 394.18310546875, + "height": 13, + "text": "+create_init_image_data()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAtcgsAaVdmuU=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVnmdQ=" + }, + "model": { + "$ref": "AAAAAAGAtcgr7KVa4xs=" + }, + "font": "Arial;13;0", + "left": 365, + "top": 389, + "width": 394.18310546875, + "height": 13, + "text": "+draw_text_data()", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 360, + "top": 264, + "width": 404.18310546875, + "height": 143 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGAXjxqhaVoJSQ=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVg3/0=" + }, + "model": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 240, + "top": 423, + "width": 467.7685546875, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGAXjxqhaVp7OU=", + "_parent": { + "$ref": "AAAAAAGAXjxqhKVg3/0=" + }, + "model": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 576.099609375, + "top": 112, + "width": 130.6689453125, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 360, + "top": 96, + "width": 404.18310546875, + "height": 311, + "nameCompartment": { + "$ref": "AAAAAAGAXjxqhKVhfuo=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGAXjxqhKVmFgA=" + }, + "operationCompartment": { + "$ref": "AAAAAAGAXjxqhKVnmdQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGAXjxqhaVoJSQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGAXjxqhaVp7OU=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGAk4Bm7aZpz/0=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGAk4Bm7qZqCE0=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZpz/0=" + }, + "model": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGAk4Bm7qZr+e0=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7qZqCE0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -119.75390625, + "top": 704, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAk4Bm7qZs/Io=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7qZqCE0=" + }, + "font": "Arial;13;1", + "left": 581, + "top": 423, + "width": 180.29248046875, + "height": 13, + "text": "BattleMode" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAk4Bm7qZtSmM=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7qZqCE0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -119.75390625, + "top": 704, + "width": 80.5009765625, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAk4Bm7qZuKO0=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7qZqCE0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -119.75390625, + "top": 704, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 576, + "top": 416, + "width": 190.29248046875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGAk4Bm7qZr+e0=" + }, + "nameLabel": { + "$ref": "AAAAAAGAk4Bm7qZs/Io=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGAk4Bm7qZtSmM=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAk4Bm7qZuKO0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGAk4Bm76ZveFI=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZpz/0=" + }, + "model": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk4VFMKjuSLk=", + "_parent": { + "$ref": "AAAAAAGAk4Bm76ZveFI=" + }, + "model": { + "$ref": "AAAAAAGAk4VFJajrfOU=" + }, + "font": "Arial;13;0", + "left": 581, + "top": 446, + "width": 180.29248046875, + "height": 13, + "text": "+player_2P: sprite", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl1ODOCYWYvI=", + "_parent": { + "$ref": "AAAAAAGAk4Bm76ZveFI=" + }, + "model": { + "$ref": "AAAAAAGAl1ODLSYTr98=" + }, + "font": "Arial;13;0", + "left": 581, + "top": 461, + "width": 180.29248046875, + "height": 13, + "text": "+is_invincible: Bool", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl1PKdipOYaE=", + "_parent": { + "$ref": "AAAAAAGAk4Bm76ZveFI=" + }, + "model": { + "$ref": "AAAAAAGAl1PKaSpLQKM=" + }, + "font": "Arial;13;0", + "left": 581, + "top": 476, + "width": 180.29248046875, + "height": 13, + "text": "+is_through_wall: Bool", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl1aZozObuwc=", + "_parent": { + "$ref": "AAAAAAGAk4Bm76ZveFI=" + }, + "model": { + "$ref": "AAAAAAGAl1aZlTOYSFU=" + }, + "font": "Arial;13;0", + "left": 581, + "top": 491, + "width": 180.29248046875, + "height": 13, + "text": "+is_debug: Bool", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAmCsj9cv2NVk=", + "_parent": { + "$ref": "AAAAAAGAk4Bm76ZveFI=" + }, + "model": { + "$ref": "AAAAAAGAmCsj48vzQzY=" + }, + "font": "Arial;13;0", + "left": 581, + "top": 506, + "width": 180.29248046875, + "height": 13, + "text": "+players: Group", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAmCtP7szDy5U=", + "_parent": { + "$ref": "AAAAAAGAk4Bm76ZveFI=" + }, + "model": { + "$ref": "AAAAAAGAmCtP1szA3Lk=" + }, + "font": "Arial;13;0", + "left": 581, + "top": 521, + "width": 180.29248046875, + "height": 13, + "text": "+walls: Group", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAmCt9Vs20WxQ=", + "_parent": { + "$ref": "AAAAAAGAk4Bm76ZveFI=" + }, + "model": { + "$ref": "AAAAAAGAmCt9Oc2xkSk=" + }, + "font": "Arial;13;0", + "left": 581, + "top": 536, + "width": 180.29248046875, + "height": 13, + "text": "+bullets: Group", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAmCu0Vc6lhlE=", + "_parent": { + "$ref": "AAAAAAGAk4Bm76ZveFI=" + }, + "model": { + "$ref": "AAAAAAGAmCu0Q86iDIA=" + }, + "font": "Arial;13;0", + "left": 581, + "top": 551, + "width": 180.29248046875, + "height": 13, + "text": "+player_1P: sprite", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 576, + "top": 441, + "width": 190.29248046875, + "height": 128 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGAk4Bm76Zw1Xw=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZpz/0=" + }, + "model": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAq751YuNJ2eg=", + "_parent": { + "$ref": "AAAAAAGAk4Bm76Zw1Xw=" + }, + "model": { + "$ref": "AAAAAAGAq751PONGLwk=" + }, + "font": "Arial;13;0", + "left": 581, + "top": 574, + "width": 180.29248046875, + "height": 13, + "text": "+create_bullte(shoot_info: Dict)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAtepAK7C2mW4=", + "_parent": { + "$ref": "AAAAAAGAk4Bm76Zw1Xw=" + }, + "model": { + "$ref": "AAAAAAGAtepAErCzCDo=" + }, + "font": "Arial;13;0", + "left": 581, + "top": 589, + "width": 180.29248046875, + "height": 13, + "text": "+draw_sprite_data(): list", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAtep9Z7Fz12E=", + "_parent": { + "$ref": "AAAAAAGAk4Bm76Zw1Xw=" + }, + "model": { + "$ref": "AAAAAAGAtep9JrFwneU=" + }, + "font": "Arial;13;0", + "left": 581, + "top": 604, + "width": 180.29248046875, + "height": 13, + "text": "+create_init_image_data(): list", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAteq33rJOgvA=", + "_parent": { + "$ref": "AAAAAAGAk4Bm76Zw1Xw=" + }, + "model": { + "$ref": "AAAAAAGAteq3xbJLFFI=" + }, + "font": "Arial;13;0", + "left": 581, + "top": 619, + "width": 180.29248046875, + "height": 13, + "text": "+draw_text_data(): list", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 576, + "top": 569, + "width": 190.29248046875, + "height": 68 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGAk4Bm76Zxl3k=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZpz/0=" + }, + "model": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -59.876953125, + "top": 352, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGAk4Bm76ZyuiE=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZpz/0=" + }, + "model": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -59.876953125, + "top": 352, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 576, + "top": 416, + "width": 190.29248046875, + "height": 221, + "nameCompartment": { + "$ref": "AAAAAAGAk4Bm7qZqCE0=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGAk4Bm76ZveFI=" + }, + "operationCompartment": { + "$ref": "AAAAAAGAk4Bm76Zw1Xw=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGAk4Bm76Zxl3k=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGAk4Bm76ZyuiE=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGAk4i0r6t962o=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGAk4i0r6t+wI0=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6t962o=" + }, + "model": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGAk4i0r6t/y6M=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6t+wI0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -640, + "top": 48, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAk4i0r6uA39Y=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6t+wI0=" + }, + "font": "Arial;13;1", + "left": 29, + "top": 31, + "width": 318.5, + "height": 13, + "text": "MyGame" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAk4i0r6uB5nI=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6t+wI0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -640, + "top": 48, + "width": 80.5009765625, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAk4i0r6uCuto=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6t+wI0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -640, + "top": 48, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 24, + "top": 24, + "width": 328.5, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGAk4i0r6t/y6M=" + }, + "nameLabel": { + "$ref": "AAAAAAGAk4i0r6uA39Y=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGAk4i0r6uB5nI=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAk4i0r6uCuto=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGAk4i0r6uDN3g=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6t962o=" + }, + "model": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlvY4CzFRUfg=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6uDN3g=" + }, + "model": { + "$ref": "AAAAAAGAlvY38TFLyd8=" + }, + "font": "Arial;13;0", + "left": 29, + "top": 54, + "width": 318.5, + "height": 13, + "text": "+scene: Scene", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk4kgA6ybYog=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6uDN3g=" + }, + "model": { + "$ref": "AAAAAAGAk4kf+KyVMfg=" + }, + "font": "Arial;13;0", + "left": 29, + "top": 69, + "width": 318.5, + "height": 13, + "text": "+attachements: List", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk4l9CKzDTl0=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6uDN3g=" + }, + "model": { + "$ref": "AAAAAAGAk4l896y9t7w=" + }, + "font": "Arial;13;0", + "left": 29, + "top": 84, + "width": 318.5, + "height": 13, + "text": "+game_mode: Q", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk4qz5qzxHNU=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6uDN3g=" + }, + "model": { + "$ref": "AAAAAAGAk4qz3azr1dY=" + }, + "font": "Arial;13;0", + "left": 29, + "top": 99, + "width": 318.5, + "height": 13, + "text": "+sound: Str", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk4uV8q0fse8=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6uDN3g=" + }, + "model": { + "$ref": "AAAAAAGAk4uV6a0Zir8=" + }, + "font": "Arial;13;0", + "left": 29, + "top": 114, + "width": 318.5, + "height": 13, + "text": "+map_path: Str", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 24, + "top": 49, + "width": 328.5, + "height": 83 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGAk4i0r6uEj2E=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6t962o=" + }, + "model": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAlvcFUDJ81VM=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6uEj2E=" + }, + "model": { + "$ref": "AAAAAAGAlvcFRzJ2WKg=" + }, + "font": "Arial;13;0", + "left": 29, + "top": 137, + "width": 318.5, + "height": 13, + "text": "-__init__(map_no: int, sound: str)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk5zhEdNShKA=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6uEj2E=" + }, + "model": { + "$ref": "AAAAAAGAk5zhAtNMoaw=" + }, + "font": "Arial;13;0", + "left": 29, + "top": 152, + "width": 318.5, + "height": 13, + "text": "+get_scene_info(): Dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk52n7tP4qoQ=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6uEj2E=" + }, + "model": { + "$ref": "AAAAAAGAk52n3dPyZ8c=" + }, + "font": "Arial;13;0", + "left": 29, + "top": 167, + "width": 318.5, + "height": 13, + "text": "+is_running(): Bool", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk54ny9RB5j4=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6uEj2E=" + }, + "model": { + "$ref": "AAAAAAGAk54nv9Q7Idw=" + }, + "font": "Arial;13;0", + "left": 29, + "top": 182, + "width": 318.5, + "height": 13, + "text": "+set_game_mode(game_path: Str, is_sound: Bool): Q", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk6KdYdwc+vo=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6uEj2E=" + }, + "model": { + "$ref": "AAAAAAGAk6KdVtwW3yQ=" + }, + "font": "Arial;13;0", + "left": 29, + "top": 197, + "width": 318.5, + "height": 13, + "text": "+rank(): List", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 24, + "top": 132, + "width": 328.5, + "height": 83 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGAk4i0r6uFBB8=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6t962o=" + }, + "model": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -344, + "top": 376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGAk4i0r6uGRCI=", + "_parent": { + "$ref": "AAAAAAGAk4i0r6t962o=" + }, + "model": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -344, + "top": 376, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 24, + "top": 24, + "width": 328.5, + "height": 191, + "nameCompartment": { + "$ref": "AAAAAAGAk4i0r6t+wI0=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGAk4i0r6uDN3g=" + }, + "operationCompartment": { + "$ref": "AAAAAAGAk4i0r6uEj2E=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGAk4i0r6uFBB8=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGAk4i0r6uGRCI=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAGAk5CJqcAtdYk=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAk5CJqcAr7io=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAk5CJqcAubIk=", + "_parent": { + "$ref": "AAAAAAGAk5CJqcAtdYk=" + }, + "model": { + "$ref": "AAAAAAGAk5CJqcAr7io=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 786, + "top": 404, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGAk5CJqcAtdYk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAk5CJqcAvgl8=", + "_parent": { + "$ref": "AAAAAAGAk5CJqcAtdYk=" + }, + "model": { + "$ref": "AAAAAAGAk5CJqcAr7io=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 777, + "top": 392, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGAk5CJqcAtdYk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAk5CJqcAwXOw=", + "_parent": { + "$ref": "AAAAAAGAk5CJqcAtdYk=" + }, + "model": { + "$ref": "AAAAAAGAk5CJqcAr7io=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 805, + "top": 427, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGAk5CJqcAtdYk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAux1Tbu7gIiM=" + }, + "tail": { + "$ref": "AAAAAAGAk4Bm7aZpz/0=" + }, + "lineStyle": 1, + "points": "766:447;827:397", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGAk5CJqcAubIk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGAk5CJqcAvgl8=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAk5CJqcAwXOw=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGAk5DXD8IZ4r8=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGAk5DXD8IaSU8=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IZ4r8=" + }, + "model": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGAk5DXD8Ib+pI=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IaSU8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -160, + "top": 488, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAk5DXD8IcbA8=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IaSU8=" + }, + "font": "Arial;13;1", + "left": 21, + "top": 255, + "width": 201.59521484375, + "height": 13, + "text": "PaiaGame" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAk5DXEMIdke8=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IaSU8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -160, + "top": 488, + "width": 80.5009765625, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAk5DXEMIehaA=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IaSU8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -160, + "top": 488, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 16, + "top": 248, + "width": 211.59521484375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGAk5DXD8Ib+pI=" + }, + "nameLabel": { + "$ref": "AAAAAAGAk5DXD8IcbA8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGAk5DXEMIdke8=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAk5DXEMIehaA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGAk5DXEMIfFPU=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IZ4r8=" + }, + "model": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk5G7IsROG2U=", + "_parent": { + "$ref": "AAAAAAGAk5DXEMIfFPU=" + }, + "model": { + "$ref": "AAAAAAGAk5G7FsRFRTg=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 278, + "width": 201.59521484375, + "height": 13, + "text": "+scene: Scene", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk5H9TcSXHAo=", + "_parent": { + "$ref": "AAAAAAGAk5DXEMIfFPU=" + }, + "model": { + "$ref": "AAAAAAGAk5H9QsSOiRk=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 293, + "width": 201.59521484375, + "height": 13, + "text": "+frame_count: Int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk5I3I8TsSMs=", + "_parent": { + "$ref": "AAAAAAGAk5DXEMIfFPU=" + }, + "model": { + "$ref": "AAAAAAGAk5I3GsTjZv4=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 308, + "width": 201.59521484375, + "height": 13, + "text": "+game_result_state: Str", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 16, + "top": 273, + "width": 211.59521484375, + "height": 53 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGAk5DXEMIgZ94=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IZ4r8=" + }, + "model": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk5W54MWzVno=", + "_parent": { + "$ref": "AAAAAAGAk5DXEMIgZ94=" + }, + "model": { + "$ref": "AAAAAAGAk5W51cWqrZ4=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 331, + "width": 201.59521484375, + "height": 13, + "text": "-__init__(): None", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk5XwtcYJ9VM=", + "_parent": { + "$ref": "AAAAAAGAk5DXEMIgZ94=" + }, + "model": { + "$ref": "AAAAAAGAk5XwpMYA/gU=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 346, + "width": 201.59521484375, + "height": 13, + "text": "+update(commands: Dict): None", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk5a2Iscr8jY=", + "_parent": { + "$ref": "AAAAAAGAk5DXEMIgZ94=" + }, + "model": { + "$ref": "AAAAAAGAk5a2GMciKVk=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 361, + "width": 201.59521484375, + "height": 13, + "text": "+game_to_player_data(): Dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk5dBTMeIj9Q=", + "_parent": { + "$ref": "AAAAAAGAk5DXEMIgZ94=" + }, + "model": { + "$ref": "AAAAAAGAk5dBQsd/Tmw=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 376, + "width": 201.59521484375, + "height": 13, + "text": "+reset(): None", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk5domMflXek=", + "_parent": { + "$ref": "AAAAAAGAk5DXEMIgZ94=" + }, + "model": { + "$ref": "AAAAAAGAk5dojsfcCqM=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 391, + "width": 201.59521484375, + "height": 13, + "text": "+get_scene_init_data(): Dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk5fEPMhCQh4=", + "_parent": { + "$ref": "AAAAAAGAk5DXEMIgZ94=" + }, + "model": { + "$ref": "AAAAAAGAk5fEMsg5d4g=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 406, + "width": 201.59521484375, + "height": 13, + "text": "+get_scene_progress_data(): Dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk5gs98ifyUA=", + "_parent": { + "$ref": "AAAAAAGAk5DXEMIgZ94=" + }, + "model": { + "$ref": "AAAAAAGAk5gs7ciWGr0=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 421, + "width": 201.59521484375, + "height": 13, + "text": "+get_game_result(): Dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk5iCs8j8mrU=", + "_parent": { + "$ref": "AAAAAAGAk5DXEMIgZ94=" + }, + "model": { + "$ref": "AAAAAAGAk5iCl8jzZ5c=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 436, + "width": 201.59521484375, + "height": 13, + "text": "+get_keyboard_command(): Dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk5jVyMlZq9w=", + "_parent": { + "$ref": "AAAAAAGAk5DXEMIgZ94=" + }, + "model": { + "$ref": "AAAAAAGAk5jVvclQBvY=" + }, + "font": "Arial;13;0", + "left": 21, + "top": 451, + "width": 201.59521484375, + "height": 13, + "text": "+ai_clients(): List", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 16, + "top": 326, + "width": 211.59521484375, + "height": 143 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGAk5DXEMIhvH8=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IZ4r8=" + }, + "model": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -88, + "top": 12, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGAk5DXEMIiohQ=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IZ4r8=" + }, + "model": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -88, + "top": 12, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 16, + "top": 248, + "width": 211.59521484375, + "height": 236, + "nameCompartment": { + "$ref": "AAAAAAGAk5DXD8IaSU8=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGAk5DXEMIfFPU=" + }, + "operationCompartment": { + "$ref": "AAAAAAGAk5DXEMIgZ94=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGAk5DXEMIhvH8=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGAk5DXEMIiohQ=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAGAk5DXmsJgVjE=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAk5DXmsJevOw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAk5DXm8JhxFo=", + "_parent": { + "$ref": "AAAAAAGAk5DXmsJgVjE=" + }, + "model": { + "$ref": "AAAAAAGAk5DXmsJevOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 171, + "top": 228, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGAk5DXmsJgVjE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAk5DXm8Ji+y8=", + "_parent": { + "$ref": "AAAAAAGAk5DXmsJgVjE=" + }, + "model": { + "$ref": "AAAAAAGAk5DXmsJevOw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 186, + "top": 232, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGAk5DXmsJgVjE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAk5DXm8JjUqk=", + "_parent": { + "$ref": "AAAAAAGAk5DXmsJgVjE=" + }, + "model": { + "$ref": "AAAAAAGAk5DXmsJevOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 142, + "top": 221, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGAk5DXmsJgVjE=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAk5DXD8IZ4r8=" + }, + "tail": { + "$ref": "AAAAAAGAk4i0r6t962o=" + }, + "lineStyle": 1, + "points": "161:215;153:247", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGAk5DXm8JhxFo=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGAk5DXm8Ji+y8=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAk5DXm8JjUqk=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGAk6h2wehM6EA=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGAk6h2wuhNu7g=", + "_parent": { + "$ref": "AAAAAAGAk6h2wehM6EA=" + }, + "model": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGAk6h2wuhOXKU=", + "_parent": { + "$ref": "AAAAAAGAk6h2wuhNu7g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -768, + "top": 232, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAk6h2wuhP+6c=", + "_parent": { + "$ref": "AAAAAAGAk6h2wuhNu7g=" + }, + "font": "Arial;13;1", + "left": 261, + "top": 423, + "width": 277.1005859375, + "height": 13, + "text": "TiledMap" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAk6h2wuhQbJw=", + "_parent": { + "$ref": "AAAAAAGAk6h2wuhNu7g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -768, + "top": 232, + "width": 80.5009765625, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAk6h2wuhRme8=", + "_parent": { + "$ref": "AAAAAAGAk6h2wuhNu7g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -768, + "top": 232, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 256, + "top": 416, + "width": 287.1005859375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGAk6h2wuhOXKU=" + }, + "nameLabel": { + "$ref": "AAAAAAGAk6h2wuhP+6c=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGAk6h2wuhQbJw=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAk6h2wuhRme8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGAk6h2wuhSoMU=", + "_parent": { + "$ref": "AAAAAAGAk6h2wehM6EA=" + }, + "model": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk6urkPGUWjE=", + "_parent": { + "$ref": "AAAAAAGAk6h2wuhSoMU=" + }, + "model": { + "$ref": "AAAAAAGAk6urfvGImRk=" + }, + "font": "Arial;13;0", + "left": 261, + "top": 446, + "width": 277.1005859375, + "height": 13, + "text": "+width: Int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk6vszfH+NxY=", + "_parent": { + "$ref": "AAAAAAGAk6h2wuhSoMU=" + }, + "model": { + "$ref": "AAAAAAGAk6vsvvHyyiw=" + }, + "font": "Arial;13;0", + "left": 261, + "top": 461, + "width": 277.1005859375, + "height": 13, + "text": "+height: Int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAk6wt4vMBLAI=", + "_parent": { + "$ref": "AAAAAAGAk6h2wuhSoMU=" + }, + "model": { + "$ref": "AAAAAAGAk6wt1vL1d7s=" + }, + "font": "Arial;13;0", + "left": 261, + "top": 476, + "width": 277.1005859375, + "height": 13, + "text": "+tmx_data: pytmx.pytmx.TieldMap", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 256, + "top": 441, + "width": 287.1005859375, + "height": 53 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGAk6h2wuhTxI0=", + "_parent": { + "$ref": "AAAAAAGAk6h2wehM6EA=" + }, + "model": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk6ksCe4OGQg=", + "_parent": { + "$ref": "AAAAAAGAk6h2wuhTxI0=" + }, + "model": { + "$ref": "AAAAAAGAk6kr/O4CXBo=" + }, + "font": "Arial;13;0", + "left": 261, + "top": 499, + "width": 277.1005859375, + "height": 13, + "text": "+creat_img_init_data(img_no_list: List): List", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk6l+2u54DCQ=", + "_parent": { + "$ref": "AAAAAAGAk6h2wuhTxI0=" + }, + "model": { + "$ref": "AAAAAAGAk6l+y+5sE9E=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 285, + "top": 346, + "width": 313.9677734375, + "height": 13, + "text": "+creat_walls_init_data(walls_img_no_list: List): List", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAk6phAPChJiA=", + "_parent": { + "$ref": "AAAAAAGAk6h2wuhTxI0=" + }, + "model": { + "$ref": "AAAAAAGAk6pg8fCVFEY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 285, + "top": 346, + "width": 313.9677734375, + "height": 13, + "text": "+creat_mobs_init_data(mobs_img_no_list: List): List", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGArQUJmV61oCY=", + "_parent": { + "$ref": "AAAAAAGAk6h2wuhTxI0=" + }, + "model": { + "$ref": "AAAAAAGArQUJgl6yVkg=" + }, + "font": "Arial;13;0", + "left": 261, + "top": 514, + "width": 277.1005859375, + "height": 13, + "text": "-__init__(map_no: int, time_limit: int, sound: str)", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 256, + "top": 494, + "width": 287.1005859375, + "height": 38 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGAk6h2wuhU99M=", + "_parent": { + "$ref": "AAAAAAGAk6h2wehM6EA=" + }, + "model": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -288, + "top": 172, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGAk6h2wuhVloA=", + "_parent": { + "$ref": "AAAAAAGAk6h2wehM6EA=" + }, + "model": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -288, + "top": 172, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 256, + "top": 416, + "width": 287.1005859375, + "height": 116, + "nameCompartment": { + "$ref": "AAAAAAGAk6h2wuhNu7g=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGAk6h2wuhSoMU=" + }, + "operationCompartment": { + "$ref": "AAAAAAGAk6h2wuhTxI0=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGAk6h2wuhU99M=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGAk6h2wuhVloA=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGAlv9Mx0pY6qQ=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGAlv9Mx0pZhO0=", + "_parent": { + "$ref": "AAAAAAGAlv9Mx0pY6qQ=" + }, + "model": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGAlv9Mx0paOYA=", + "_parent": { + "$ref": "AAAAAAGAlv9Mx0pZhO0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 448, + "top": -44, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAlv9Mx0pbtOw=", + "_parent": { + "$ref": "AAAAAAGAlv9Mx0pZhO0=" + }, + "font": "Arial;13;1", + "left": 997, + "top": 343, + "width": 170.5234375, + "height": 13, + "text": "Player" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAlv9Mx0pcbck=", + "_parent": { + "$ref": "AAAAAAGAlv9Mx0pZhO0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 448, + "top": -44, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAlv9Mx0pdb84=", + "_parent": { + "$ref": "AAAAAAGAlv9Mx0pZhO0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 448, + "top": -44, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 992, + "top": 336, + "width": 180.5234375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGAlv9Mx0paOYA=" + }, + "nameLabel": { + "$ref": "AAAAAAGAlv9Mx0pbtOw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGAlv9Mx0pcbck=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAlv9Mx0pdb84=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGAlv9MyEpe3uI=", + "_parent": { + "$ref": "AAAAAAGAlv9Mx0pY6qQ=" + }, + "model": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlwJoeV/2edA=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "model": { + "$ref": "AAAAAAGAlwJoZ1/tBu0=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 366, + "width": 170.5234375, + "height": 13, + "text": "+img_id: str", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlwGUd1376rk=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "model": { + "$ref": "AAAAAAGAlwGUa13yup4=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 381, + "width": 170.5234375, + "height": 13, + "text": "+is_shoot: Bool", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlwMnQWKNXEI=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "model": { + "$ref": "AAAAAAGAlwMnN2KEupU=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 396, + "width": 170.5234375, + "height": 13, + "text": "+is_backward: Bool", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlwOVBmMwtsk=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "model": { + "$ref": "AAAAAAGAlwOU8WMn6Wc=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 411, + "width": 170.5234375, + "height": 13, + "text": "+is_forward: Bool", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlwPf8WeTv4c=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "model": { + "$ref": "AAAAAAGAlwPf6GeKsQk=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 426, + "width": 170.5234375, + "height": 13, + "text": "+last_shoot_fram: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlwR9n2g22ak=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "model": { + "$ref": "AAAAAAGAlwR9kGgtS2k=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 441, + "width": 170.5234375, + "height": 13, + "text": "+shoot_delay: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlwTts2xqMfk=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "model": { + "$ref": "AAAAAAGAlwTtomxhH4o=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 456, + "width": 170.5234375, + "height": 13, + "text": "+shield: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlwdG4HGm9+g=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "model": { + "$ref": "AAAAAAGAlwdG1XGdV3I=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 471, + "width": 170.5234375, + "height": 13, + "text": "+rot: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlwdqMHJJf0w=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "model": { + "$ref": "AAAAAAGAlwdqIHJA7mw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1101, + "top": 828, + "width": 211.35791015625, + "height": 13, + "text": "+rot_speed: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlwW7wG2q6Ss=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "model": { + "$ref": "AAAAAAGAlwW7rW2h/mA=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 486, + "width": 170.5234375, + "height": 13, + "text": "+move: List", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlwibkXTVp6A=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "model": { + "$ref": "AAAAAAGAlwibfnTMDYs=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 501, + "width": 170.5234375, + "height": 13, + "text": "+surface: Surface", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlwk/RXa+dAQ=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "model": { + "$ref": "AAAAAAGAlwk/Nna1N4Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1077, + "top": 886, + "width": 136.92529296875, + "height": 13, + "text": "+Attribute1", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArUoSfJBjhiE=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "model": { + "$ref": "AAAAAAGArUoSY5Bgse4=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 516, + "width": 170.5234375, + "height": 13, + "text": "+angle: Float", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 992, + "top": 361, + "width": 180.5234375, + "height": 173 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGAlv9MyEpf2Ec=", + "_parent": { + "$ref": "AAAAAAGAlv9Mx0pY6qQ=" + }, + "model": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAlwn1BIAzLCo=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "model": { + "$ref": "AAAAAAGAlwn094AqVB0=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 539, + "width": 170.5234375, + "height": 13, + "text": "-__init__(_no: int, x: int, y: int)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAlwpCMYEBCeo=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "model": { + "$ref": "AAAAAAGAlwpCJoD4hM4=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 554, + "width": 170.5234375, + "height": 13, + "text": "+update(command: Dic)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAlwqMRoGayT8=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "model": { + "$ref": "AAAAAAGAlwqMMIGRwsA=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 569, + "width": 170.5234375, + "height": 13, + "text": "+act(commands: Dic)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAlws/54MYAqk=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "model": { + "$ref": "AAAAAAGAlws/04MPOTg=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 584, + "width": 170.5234375, + "height": 13, + "text": "+forward()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAlwtheoO7yhU=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "model": { + "$ref": "AAAAAAGAlwthaYOyjnQ=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 599, + "width": 170.5234375, + "height": 13, + "text": "+backward()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAlwt+3oReS/0=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "model": { + "$ref": "AAAAAAGAlwt+z4RV5c4=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 614, + "width": 170.5234375, + "height": 13, + "text": "+turn_left()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAlwuZGYUB5Vg=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "model": { + "$ref": "AAAAAAGAlwuZCYT4X14=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 629, + "width": 170.5234375, + "height": 13, + "text": "+turn_right()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAlwwF8obqJr0=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "model": { + "$ref": "AAAAAAGAlwwF3obhmr0=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 644, + "width": 170.5234375, + "height": 13, + "text": "+collide_with_walls()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAlwwt6IeNlQU=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "model": { + "$ref": "AAAAAAGAlwwt14eEiHY=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 659, + "width": 170.5234375, + "height": 13, + "text": "+collide_with_bullets()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAl2lm5lFj/Z8=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "model": { + "$ref": "AAAAAAGAl2lm1lFgub0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1213, + "top": 722, + "width": 170.5234375, + "height": 13, + "text": "+create_shoot_info(): dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAl2qJLlMOaLA=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "model": { + "$ref": "AAAAAAGAl2qJGlMLItA=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 674, + "width": 170.5234375, + "height": 13, + "text": "+rotate()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAq8OBx+ZYiD8=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "model": { + "$ref": "AAAAAAGAq8OBs+ZVm28=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 689, + "width": 170.5234375, + "height": 13, + "text": "+create_shoot_info(): dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGArUpRQpUaoHI=", + "_parent": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "model": { + "$ref": "AAAAAAGArUpRK5UXbhM=" + }, + "font": "Arial;13;0", + "left": 997, + "top": 704, + "width": 170.5234375, + "height": 13, + "text": "+get_image_data(): dict", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 992, + "top": 534, + "width": 180.5234375, + "height": 188 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGAlv9MyEpgjz4=", + "_parent": { + "$ref": "AAAAAAGAlv9Mx0pY6qQ=" + }, + "model": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 224, + "top": -22, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGAlv9MyEphQ6U=", + "_parent": { + "$ref": "AAAAAAGAlv9Mx0pY6qQ=" + }, + "model": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 224, + "top": -22, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 992, + "top": 336, + "width": 180.5234375, + "height": 386, + "nameCompartment": { + "$ref": "AAAAAAGAlv9Mx0pZhO0=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGAlv9MyEpe3uI=" + }, + "operationCompartment": { + "$ref": "AAAAAAGAlv9MyEpf2Ec=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGAlv9MyEpgjz4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGAlv9MyEphQ6U=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGAlw1a9IrL4dk=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGAlw1a9IrMeBs=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrL4dk=" + }, + "model": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGAlw1a9IrN1Bs=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrMeBs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1824, + "top": -170, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAlw1a9IrOVxU=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrMeBs=" + }, + "font": "Arial;13;1", + "left": 5, + "top": 703, + "width": 288.6787109375, + "height": 13, + "text": "Obstacle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAlw1a9IrP9gw=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrMeBs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1824, + "top": -170, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAlw1a9IrQtDI=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrMeBs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1824, + "top": -170, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "top": 696, + "width": 298.6787109375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGAlw1a9IrN1Bs=" + }, + "nameLabel": { + "$ref": "AAAAAAGAlw1a9IrOVxU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGAlw1a9IrP9gw=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAlw1a9IrQtDI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGAlw1a9IrRNwU=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrL4dk=" + }, + "model": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlw22ZI7Zsgc=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrRNwU=" + }, + "model": { + "$ref": "AAAAAAGAlw22UY7K4Ig=" + }, + "font": "Arial;13;0", + "left": 5, + "top": 726, + "width": 288.6787109375, + "height": 13, + "text": "+rect_ Rect", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlw3Xt4+F++s=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrRNwU=" + }, + "model": { + "$ref": "AAAAAAGAlw3Xno92lR8=" + }, + "font": "Arial;13;0", + "left": 5, + "top": 741, + "width": 288.6787109375, + "height": 13, + "text": "+hit_rect: Rect", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlw4hFZBPDx4=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrRNwU=" + }, + "model": { + "$ref": "AAAAAAGAlw4hA5BA2UQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -387, + "top": 1060, + "width": 210.35791015625, + "height": 13, + "text": "+pos: Vector2", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAlw75AJRRjBE=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrRNwU=" + }, + "model": { + "$ref": "AAAAAAGAlw748pRCH1Q=" + }, + "font": "Arial;13;0", + "left": 5, + "top": 756, + "width": 288.6787109375, + "height": 13, + "text": "+lives: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArBgSPQYySr4=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrRNwU=" + }, + "model": { + "$ref": "AAAAAAGArBgSKQYpZa8=" + }, + "font": "Arial;13;0", + "left": 5, + "top": 771, + "width": 288.6787109375, + "height": 13, + "text": "#_no: int", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "top": 721, + "width": 298.6787109375, + "height": 68 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGAlw1a9IrSjAU=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrL4dk=" + }, + "model": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAlw5+w5IYpT4=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrSjAU=" + }, + "model": { + "$ref": "AAAAAAGAlw5+s5IJsbI=" + }, + "font": "Arial;13;0", + "left": 5, + "top": 794, + "width": 288.6787109375, + "height": 13, + "text": "+updata()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAlw67aZLE+h8=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrSjAU=" + }, + "model": { + "$ref": "AAAAAAGAlw67WJK1kyc=" + }, + "font": "Arial;13;0", + "left": 5, + "top": 809, + "width": 288.6787109375, + "height": 13, + "text": "+get_position(): Tuple", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGArBePAQFs+5I=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrSjAU=" + }, + "model": { + "$ref": "AAAAAAGArBeO6QFjVkw=" + }, + "font": "Arial;13;0", + "left": 5, + "top": 824, + "width": 288.6787109375, + "height": 13, + "text": "+collide_with_bullets()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGArP0e7UMxD/Q=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrSjAU=" + }, + "model": { + "$ref": "AAAAAAGArP0eyUMoi6I=" + }, + "font": "Arial;13;0", + "left": 5, + "top": 839, + "width": 288.6787109375, + "height": 13, + "text": "-__init__(no: int, x: int, y: int, width: int, height: int)", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "top": 789, + "width": 298.6787109375, + "height": 68 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGAlw1a9IrT+tA=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrL4dk=" + }, + "model": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1096, + "top": -93, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGAlw1a9IrUxfs=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrL4dk=" + }, + "model": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1096, + "top": -93, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "top": 696, + "width": 298.6787109375, + "height": 161, + "nameCompartment": { + "$ref": "AAAAAAGAlw1a9IrMeBs=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGAlw1a9IrRNwU=" + }, + "operationCompartment": { + "$ref": "AAAAAAGAlw1a9IrSjAU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGAlw1a9IrT+tA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGAlw1a9IrUxfs=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGAl12L1ka5A8Q=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGAl12L1ka6NJ4=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka5A8Q=" + }, + "model": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGAl12L1ka7P2I=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka6NJ4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 272, + "top": 16, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAl12L1ka8ckg=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka6NJ4=" + }, + "font": "Arial;13;1", + "left": 1029, + "top": 15, + "width": 139.08984375, + "height": 13, + "text": "Player" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAl12L1ka9ebA=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka6NJ4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 272, + "top": 16, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAl12L1ka+OH4=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka6NJ4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 272, + "top": 16, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1024, + "top": 8, + "width": 149.08984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGAl12L1ka7P2I=" + }, + "nameLabel": { + "$ref": "AAAAAAGAl12L1ka8ckg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGAl12L1ka9ebA=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAl12L1ka+OH4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGAl12L1ka/mhk=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka5A8Q=" + }, + "model": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl398qJKqDvw=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "model": { + "$ref": "AAAAAAGAl3x7tYZrEgc=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 38, + "width": 139.08984375, + "height": 13, + "text": "+hit_rect: pygame.Rect", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl3+CMpMcxwo=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "model": { + "$ref": "AAAAAAGAl31Nc4jZfC8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1269, + "top": 53, + "width": 139.08984375, + "height": 13, + "text": "+img_path: str", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl3+Hw5OOYsU=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "model": { + "$ref": "AAAAAAGAl34Jtou/xeM=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 53, + "width": 139.08984375, + "height": 13, + "text": "+player_info: Dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl3/jAJYEckM=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "model": { + "$ref": "AAAAAAGAl3/i6ZX1W/I=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 68, + "width": 139.08984375, + "height": 13, + "text": "+result_info: Dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl4FjfpjeFsA=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "model": { + "$ref": "AAAAAAGAl4FjaZjP9Js=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 901, + "top": 90, + "width": 134.037109375, + "height": 13, + "text": "+pos: Vector2", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl4L7UZvFCFQ=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "model": { + "$ref": "AAAAAAGAl4L7QJu261g=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 83, + "width": 139.08984375, + "height": 13, + "text": "+rect: pygame.Rect", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl4Vhd53T+NA=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "model": { + "$ref": "AAAAAAGAl4VhZ53EuA8=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 98, + "width": 139.08984375, + "height": 13, + "text": "+score: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl4WdzqAp1Cw=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "model": { + "$ref": "AAAAAAGAl4Wdu6AacQY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 917, + "top": 120, + "width": 211.35791015625, + "height": 13, + "text": "+speed: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl4hB2aRF/Eg=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "model": { + "$ref": "AAAAAAGAl4hBwaQ2YAk=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 113, + "width": 139.08984375, + "height": 13, + "text": "+used_frame: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl4gFRqI3oNQ=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "model": { + "$ref": "AAAAAAGAl4gFNKIok+Q=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 128, + "width": 139.08984375, + "height": 13, + "text": "+is_alive: Bool", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl4h486anD/w=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "model": { + "$ref": "AAAAAAGAl4h44qaYN9Y=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 143, + "width": 139.08984375, + "height": 13, + "text": "+vel: Vector2", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAmGGmPtct39A=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "model": { + "$ref": "AAAAAAGAmGGmHNceHdk=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 158, + "width": 139.08984375, + "height": 13, + "text": "#_no: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArT+nSIcAV9s=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "model": { + "$ref": "AAAAAAGArT+nLob0qfY=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 173, + "width": 139.08984375, + "height": 13, + "text": "+image_data: dict", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 1024, + "top": 33, + "width": 149.08984375, + "height": 158 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGAl12L1kbADQY=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka5A8Q=" + }, + "model": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAl4kQqKoG548=", + "_parent": { + "$ref": "AAAAAAGAl12L1kbADQY=" + }, + "model": { + "$ref": "AAAAAAGAl4kQlqn3uu8=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 196, + "width": 139.08984375, + "height": 13, + "text": "+update(command: Dic)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAl4qWQbK7VRI=", + "_parent": { + "$ref": "AAAAAAGAl12L1kbADQY=" + }, + "model": { + "$ref": "AAAAAAGAl4qWLbKs5LA=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 211, + "width": 139.08984375, + "height": 13, + "text": "+act(commands: Dic)", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAl4nZ1qwiy3Q=", + "_parent": { + "$ref": "AAAAAAGAl12L1kbADQY=" + }, + "model": { + "$ref": "AAAAAAGAl4nZw6wTnwM=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 226, + "width": 139.08984375, + "height": 13, + "text": "+get_info(): Dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAl4onGq5Wz6U=", + "_parent": { + "$ref": "AAAAAAGAl12L1kbADQY=" + }, + "model": { + "$ref": "AAAAAAGAl4onB65HF+4=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 241, + "width": 139.08984375, + "height": 13, + "text": "+get_result(): Dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAl4wLLbX58po=", + "_parent": { + "$ref": "AAAAAAGAl12L1kbADQY=" + }, + "model": { + "$ref": "AAAAAAGAl4wLGLXqvNE=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 256, + "width": 139.08984375, + "height": 13, + "text": "+get_position(): Tuple", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAl4x9s7hDReM=", + "_parent": { + "$ref": "AAAAAAGAl12L1kbADQY=" + }, + "model": { + "$ref": "AAAAAAGAl4x9obg0ows=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 271, + "width": 139.08984375, + "height": 13, + "text": "+player_init_data(): Dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGArT0E/nw2lyg=", + "_parent": { + "$ref": "AAAAAAGAl12L1kbADQY=" + }, + "model": { + "$ref": "AAAAAAGArT0E5nwq/LE=" + }, + "font": "Arial;13;0", + "left": 1029, + "top": 286, + "width": 139.08984375, + "height": 13, + "text": "+get_image_data()", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 1024, + "top": 191, + "width": 149.08984375, + "height": 113 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGAl12L1kbB64I=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka5A8Q=" + }, + "model": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 136, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGAl12L1kbCaUI=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka5A8Q=" + }, + "model": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 136, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1024, + "top": 8, + "width": 149.08984375, + "height": 296, + "nameCompartment": { + "$ref": "AAAAAAGAl12L1ka6NJ4=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGAl12L1ka/mhk=" + }, + "operationCompartment": { + "$ref": "AAAAAAGAl12L1kbADQY=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGAl12L1kbB64I=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGAl12L1kbCaUI=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAGAl12MsEceznU=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAl12MsEcchKs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAl12MsEcfArU=", + "_parent": { + "$ref": "AAAAAAGAl12MsEceznU=" + }, + "model": { + "$ref": "AAAAAAGAl12MsEcchKs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1075, + "top": 312, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGAl12MsEceznU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAl12MsEcgDbM=", + "_parent": { + "$ref": "AAAAAAGAl12MsEceznU=" + }, + "model": { + "$ref": "AAAAAAGAl12MsEcchKs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1060, + "top": 311, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGAl12MsEceznU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAl12MsEchIRI=", + "_parent": { + "$ref": "AAAAAAGAl12MsEceznU=" + }, + "model": { + "$ref": "AAAAAAGAl12MsEcchKs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1104, + "top": 313, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGAl12MsEceznU=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAl12L1ka5A8Q=" + }, + "tail": { + "$ref": "AAAAAAGAlv9Mx0pY6qQ=" + }, + "lineStyle": 1, + "points": "1090:335;1091:304", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGAl12MsEcfArU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGAl12MsEcgDbM=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAl12MsEchIRI=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGAl441S8CcU7A=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAl441S8CaKhY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGAl441S8Cd7Tw=", + "_parent": { + "$ref": "AAAAAAGAl441S8CcU7A=" + }, + "model": { + "$ref": "AAAAAAGAl441S8CaKhY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGAl441S8CeK/o=", + "_parent": { + "$ref": "AAAAAAGAl441S8Cd7Tw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -304, + "top": 56, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAl441S8CfcB4=", + "_parent": { + "$ref": "AAAAAAGAl441S8Cd7Tw=" + }, + "font": "Arial;13;1", + "left": 245, + "top": 567, + "width": 246.04150390625, + "height": 13, + "text": "Prop" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAl441S8CgycI=", + "_parent": { + "$ref": "AAAAAAGAl441S8Cd7Tw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -304, + "top": 56, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAl441S8ChyJE=", + "_parent": { + "$ref": "AAAAAAGAl441S8Cd7Tw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -304, + "top": 56, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 240, + "top": 560, + "width": 256.04150390625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGAl441S8CeK/o=" + }, + "nameLabel": { + "$ref": "AAAAAAGAl441S8CfcB4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGAl441S8CgycI=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAl441S8ChyJE=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGAl441S8Ci2Z4=", + "_parent": { + "$ref": "AAAAAAGAl441S8CcU7A=" + }, + "model": { + "$ref": "AAAAAAGAl441S8CaKhY=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl48EeMUoYnM=", + "_parent": { + "$ref": "AAAAAAGAl441S8Ci2Z4=" + }, + "model": { + "$ref": "AAAAAAGAl48EYsUZjkQ=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 590, + "width": 246.04150390625, + "height": 13, + "text": "+rect: pygame.Rect", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGAl4+pScmWinQ=", + "_parent": { + "$ref": "AAAAAAGAl441S8Ci2Z4=" + }, + "model": { + "$ref": "AAAAAAGAl4+pJsmHF4I=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 605, + "width": 246.04150390625, + "height": 13, + "text": "+hit_rect: Rect", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 240, + "top": 585, + "width": 256.04150390625, + "height": 38 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGAl441S8CjgDM=", + "_parent": { + "$ref": "AAAAAAGAl441S8CcU7A=" + }, + "model": { + "$ref": "AAAAAAGAl441S8CaKhY=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAl47ItMNf4UA=", + "_parent": { + "$ref": "AAAAAAGAl441S8CjgDM=" + }, + "model": { + "$ref": "AAAAAAGAl47IncNQv5A=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 628, + "width": 246.04150390625, + "height": 13, + "text": "+update()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAl4/eIMubbx8=", + "_parent": { + "$ref": "AAAAAAGAl441S8CjgDM=" + }, + "model": { + "$ref": "AAAAAAGAl4/eCsuMa9A=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 643, + "width": 246.04150390625, + "height": 13, + "text": "+get_position(): Tuple", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGArPxSekCM6hs=", + "_parent": { + "$ref": "AAAAAAGAl441S8CjgDM=" + }, + "model": { + "$ref": "AAAAAAGArPxSYkB9Khg=" + }, + "font": "Arial;13;0", + "left": 245, + "top": 658, + "width": 246.04150390625, + "height": 13, + "text": "-__init__(x: int, y: int, width: int, height: int)", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 240, + "top": 623, + "width": 256.04150390625, + "height": 53 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGAl441TMCkB7U=", + "_parent": { + "$ref": "AAAAAAGAl441S8CcU7A=" + }, + "model": { + "$ref": "AAAAAAGAl441S8CaKhY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -152, + "top": 28, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGAl441TMClmg4=", + "_parent": { + "$ref": "AAAAAAGAl441S8CcU7A=" + }, + "model": { + "$ref": "AAAAAAGAl441S8CaKhY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -152, + "top": 28, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 240, + "top": 560, + "width": 256.04150390625, + "height": 116, + "nameCompartment": { + "$ref": "AAAAAAGAl441S8Cd7Tw=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGAl441S8Ci2Z4=" + }, + "operationCompartment": { + "$ref": "AAAAAAGAl441S8CjgDM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGAl441TMCkB7U=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGAl441TMClmg4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAGAl57vqRbqIPA=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAl57vqBbm3Ro=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAl57vqhbrBRQ=", + "_parent": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "model": { + "$ref": "AAAAAAGAl57vqBbm3Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 455, + "top": 414, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAl57vqhbs148=", + "_parent": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "model": { + "$ref": "AAAAAAGAl57vqBbm3Ro=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 467, + "top": 423, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAl57vqhbt3G8=", + "_parent": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "model": { + "$ref": "AAAAAAGAl57vqBbm3Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 395, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAl57vqhbuUfI=", + "_parent": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "model": { + "$ref": "AAAAAAGAl57vqBbn1Y8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 443, + "top": 430, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAl57vqhbvDvc=", + "_parent": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "model": { + "$ref": "AAAAAAGAl57vqBbn1Y8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 452, + "top": 440, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAl57vqhbwGe8=", + "_parent": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "model": { + "$ref": "AAAAAAGAl57vqBbn1Y8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 424, + "top": 410, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAl57vqhbxOng=", + "_parent": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "model": { + "$ref": "AAAAAAGAl57vqBbo+Ck=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 468, + "top": 397, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAl57vqhbyFts=", + "_parent": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "model": { + "$ref": "AAAAAAGAl57vqBbo+Ck=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": 403, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAl57vqhbzhRM=", + "_parent": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "model": { + "$ref": "AAAAAAGAl57vqBbo+Ck=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 443, + "top": 384, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAGAl57vqhb0LIo=", + "_parent": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "model": { + "$ref": "AAAAAAGAl57vqBbn1Y8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": 120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAGAl57vqhb10SU=", + "_parent": { + "$ref": "AAAAAAGAl57vqRbqIPA=" + }, + "model": { + "$ref": "AAAAAAGAl57vqBbo+Ck=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": 120, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAk6h2wehM6EA=" + }, + "tail": { + "$ref": "AAAAAAGAXjxqhKVg3/0=" + }, + "lineStyle": 1, + "points": "447:407;441:415", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGAl57vqhbrBRQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGAl57vqhbs148=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAl57vqhbt3G8=" + }, + "showEndOrder": "hide", + "tailRoleNameLabel": { + "$ref": "AAAAAAGAl57vqhbuUfI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAGAl57vqhbvDvc=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAGAl57vqhbwGe8=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAGAl57vqhbxOng=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAGAl57vqhbyFts=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAGAl57vqhbzhRM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAGAl57vqhb0LIo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAGAl57vqhb10SU=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAGArBYryu8whqg=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGArBYrye8uD2Q=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGArBYryu8xNlU=", + "_parent": { + "$ref": "AAAAAAGArBYryu8whqg=" + }, + "model": { + "$ref": "AAAAAAGArBYrye8uD2Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "top": 666, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGArBYryu8whqg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGArBYryu8yVRc=", + "_parent": { + "$ref": "AAAAAAGArBYryu8whqg=" + }, + "model": { + "$ref": "AAAAAAGArBYrye8uD2Q=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 255, + "top": 654, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGArBYryu8whqg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGArBYryu8zJHk=", + "_parent": { + "$ref": "AAAAAAGArBYryu8whqg=" + }, + "model": { + "$ref": "AAAAAAGArBYrye8uD2Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 281, + "top": 691, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGArBYryu8whqg=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAl441S8CcU7A=" + }, + "tail": { + "$ref": "AAAAAAGAlw1a9IrL4dk=" + }, + "lineStyle": 1, + "points": "260:695;286:676", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGArBYryu8xNlU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGArBYryu8yVRc=" + }, + "propertyLabel": { + "$ref": "AAAAAAGArBYryu8zJHk=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGArBbN0/ToEwE=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGArBbN0/Tp/DY=", + "_parent": { + "$ref": "AAAAAAGArBbN0/ToEwE=" + }, + "model": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGArBbN0/TqAyg=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tp/DY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 640, + "top": 448, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGArBbN0/TrCUw=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tp/DY=" + }, + "font": "Arial;13;1", + "left": 685, + "top": 695, + "width": 289.40869140625, + "height": 13, + "text": "Bullet" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGArBbN0/Ts1b4=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tp/DY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 640, + "top": 448, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGArBbN0/Tt7M4=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tp/DY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 640, + "top": 448, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 680, + "top": 688, + "width": 299.40869140625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGArBbN0/TqAyg=" + }, + "nameLabel": { + "$ref": "AAAAAAGArBbN0/TrCUw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGArBbN0/Ts1b4=" + }, + "propertyLabel": { + "$ref": "AAAAAAGArBbN0/Tt7M4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGArBbN0/Tukyg=", + "_parent": { + "$ref": "AAAAAAGArBbN0/ToEwE=" + }, + "model": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArBiWNAhQbJo=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tukyg=" + }, + "model": { + "$ref": "AAAAAAGArBiWGQg7NCg=" + }, + "font": "Arial;13;0", + "left": 685, + "top": 718, + "width": 289.40869140625, + "height": 13, + "text": "+rect: Rect", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArBjXSQkdgmw=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tukyg=" + }, + "model": { + "$ref": "AAAAAAGArBjXLwkIRBI=" + }, + "font": "Arial;13;0", + "left": 685, + "top": 733, + "width": 289.40869140625, + "height": 13, + "text": "+hit_rect: Rect", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArBkIpAoOAOQ=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tukyg=" + }, + "model": { + "$ref": "AAAAAAGArBkIfwn5Kug=" + }, + "font": "Arial;13;0", + "left": 685, + "top": 748, + "width": 289.40869140625, + "height": 13, + "text": "+speed: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArBkvswr/fwQ=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tukyg=" + }, + "model": { + "$ref": "AAAAAAGArBkvkArqIVs=" + }, + "font": "Arial;13;0", + "left": 685, + "top": 763, + "width": 289.40869140625, + "height": 13, + "text": "+_no: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArBlZ9wvwlmk=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tukyg=" + }, + "model": { + "$ref": "AAAAAAGArBlZ4AvbJ9g=" + }, + "font": "Arial;13;0", + "left": 685, + "top": 778, + "width": 289.40869140625, + "height": 13, + "text": "+rot: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArBmAGgzh+lA=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tukyg=" + }, + "model": { + "$ref": "AAAAAAGArBl/+wzMK0o=" + }, + "font": "Arial;13;0", + "left": 685, + "top": 793, + "width": 289.40869140625, + "height": 13, + "text": "+move: dict", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArBxLFA9wbgw=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tukyg=" + }, + "model": { + "$ref": "AAAAAAGArBxK+Q9blYo=" + }, + "font": "Arial;13;0", + "left": 685, + "top": 808, + "width": 289.40869140625, + "height": 13, + "text": "+angle: float", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 680, + "top": 713, + "width": 299.40869140625, + "height": 113 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGArBbN0/Tvhms=", + "_parent": { + "$ref": "AAAAAAGArBbN0/ToEwE=" + }, + "model": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAGArJ+Euig5Cd4=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tvhms=" + }, + "model": { + "$ref": "AAAAAAGArJ+EoygkofU=" + }, + "font": "Arial;13;0", + "left": 685, + "top": 831, + "width": 289.40869140625, + "height": 13, + "text": "+update()", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGArPrWqTgzckI=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tvhms=" + }, + "model": { + "$ref": "AAAAAAGArPrWkTgeCkg=" + }, + "font": "Arial;13;0", + "left": 685, + "top": 846, + "width": 289.40869140625, + "height": 13, + "text": "-__init__(player_no: int, center: tuple, rot: int)", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 680, + "top": 826, + "width": 299.40869140625, + "height": 38 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGArBbN0/TwC58=", + "_parent": { + "$ref": "AAAAAAGArBbN0/ToEwE=" + }, + "model": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 320, + "top": 224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGArBbN0/Tx1D0=", + "_parent": { + "$ref": "AAAAAAGArBbN0/ToEwE=" + }, + "model": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 320, + "top": 224, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 680, + "top": 688, + "width": 299.40869140625, + "height": 176, + "nameCompartment": { + "$ref": "AAAAAAGArBbN0/Tp/DY=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGArBbN0/Tukyg=" + }, + "operationCompartment": { + "$ref": "AAAAAAGArBbN0/Tvhms=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGArBbN0/TwC58=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGArBbN0/Tx1D0=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGArJb5pRQtpV8=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGArJb5pRQu4Oo=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQtpV8=" + }, + "model": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGArJb5pRQvqI8=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQu4Oo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -198.521484375, + "top": 496, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGArJb5pRQwMY0=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQu4Oo=" + }, + "font": "Arial;13;1", + "left": 309, + "top": 703, + "width": 341.43408203125, + "height": 13, + "text": "Station" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGArJb5pRQxhWk=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQu4Oo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -198.521484375, + "top": 496, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGArJb5pRQyy/s=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQu4Oo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -198.521484375, + "top": 496, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 304, + "top": 696, + "width": 351.43408203125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGArJb5pRQvqI8=" + }, + "nameLabel": { + "$ref": "AAAAAAGArJb5pRQwMY0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGArJb5pRQxhWk=" + }, + "propertyLabel": { + "$ref": "AAAAAAGArJb5pRQyy/s=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGArJb5pRQzieg=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQtpV8=" + }, + "model": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArJdt4h8+3Zo=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQzieg=" + }, + "model": { + "$ref": "AAAAAAGArJdtyx8pIKU=" + }, + "font": "Arial;13;0", + "left": 309, + "top": 726, + "width": 341.43408203125, + "height": 13, + "text": "#_no: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArJfR2CGGGs8=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQzieg=" + }, + "model": { + "$ref": "AAAAAAGArJfRwCFx2g8=" + }, + "font": "Arial;13;0", + "left": 309, + "top": 741, + "width": 341.43408203125, + "height": 13, + "text": "+count_frame: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArJgKnyJ3wLk=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQzieg=" + }, + "model": { + "$ref": "AAAAAAGArJgKhyJi2sQ=" + }, + "font": "Arial;13;0", + "left": 309, + "top": 756, + "width": 341.43408203125, + "height": 13, + "text": "+power: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArPiEQyqkZKk=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQzieg=" + }, + "model": { + "$ref": "AAAAAAGArPiEKSqP6ng=" + }, + "font": "Arial;13;0", + "left": 309, + "top": 771, + "width": 341.43408203125, + "height": 13, + "text": "#_id: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArPjBOiuWTlM=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQzieg=" + }, + "model": { + "$ref": "AAAAAAGArPjBISuBBXg=" + }, + "font": "Arial;13;0", + "left": 309, + "top": 786, + "width": 341.43408203125, + "height": 13, + "text": "+count_frame: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArPkGryyHjvQ=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQzieg=" + }, + "model": { + "$ref": "AAAAAAGArPkGlixyI9Y=" + }, + "font": "Arial;13;0", + "left": 309, + "top": 801, + "width": 341.43408203125, + "height": 13, + "text": "+capacity: int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLAttributeView", + "_id": "AAAAAAGArPlEWC50cXk=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQzieg=" + }, + "model": { + "$ref": "AAAAAAGArPlELC5fJfA=" + }, + "font": "Arial;13;0", + "left": 309, + "top": 816, + "width": 341.43408203125, + "height": 13, + "text": "+cool_down: int", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 304, + "top": 721, + "width": 351.43408203125, + "height": 113 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGArJb5pRQ0OOg=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQtpV8=" + }, + "model": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAGArJhdoyUGko0=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQ0OOg=" + }, + "model": { + "$ref": "AAAAAAGArJhdeyTxoTk=" + }, + "font": "Arial;13;0", + "left": 309, + "top": 839, + "width": 341.43408203125, + "height": 13, + "text": "+get_power(): int", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGArPmCojArTus=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQ0OOg=" + }, + "model": { + "$ref": "AAAAAAGArPmCiTAWIYM=" + }, + "font": "Arial;13;0", + "left": 309, + "top": 854, + "width": 341.43408203125, + "height": 13, + "text": "-__init__(_id: int, _no: int, x: int, y: int, width: int, height: int)", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 304, + "top": 834, + "width": 351.43408203125, + "height": 38 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGArJb5pRQ1yLk=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQtpV8=" + }, + "model": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -99.2607421875, + "top": 248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGArJb5pRQ2IAA=", + "_parent": { + "$ref": "AAAAAAGArJb5pRQtpV8=" + }, + "model": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -99.2607421875, + "top": 248, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 304, + "top": 696, + "width": 351.43408203125, + "height": 176, + "nameCompartment": { + "$ref": "AAAAAAGArJb5pRQu4Oo=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGArJb5pRQzieg=" + }, + "operationCompartment": { + "$ref": "AAAAAAGArJb5pRQ0OOg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGArJb5pRQ1yLk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGArJb5pRQ2IAA=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAGArJb8MxSw3ZY=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGArJb8MhSuGlc=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGArJb8MxSxUas=", + "_parent": { + "$ref": "AAAAAAGArJb8MxSw3ZY=" + }, + "model": { + "$ref": "AAAAAAGArJb8MhSuGlc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": 687, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGArJb8MxSw3ZY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGArJb8MxSyei0=", + "_parent": { + "$ref": "AAAAAAGArJb8MxSw3ZY=" + }, + "model": { + "$ref": "AAAAAAGArJb8MhSuGlc=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 388, + "top": 695, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGArJb8MxSw3ZY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGArJb8MxSzWL8=", + "_parent": { + "$ref": "AAAAAAGArJb8MxSw3ZY=" + }, + "model": { + "$ref": "AAAAAAGArJb8MhSuGlc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 425, + "top": 670, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGArJb8MxSw3ZY=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAl441S8CcU7A=" + }, + "tail": { + "$ref": "AAAAAAGArJb5pRQtpV8=" + }, + "lineStyle": 1, + "points": "420:695;407:676", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGArJb8MxSxUas=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGArJb8MxSyei0=" + }, + "propertyLabel": { + "$ref": "AAAAAAGArJb8MxSzWL8=" + } + }, + { + "_type": "UMLDependencyView", + "_id": "AAAAAAGArRJpHmtvCes=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGArRJpHmtwCyE=", + "_parent": { + "$ref": "AAAAAAGArRJpHmtvCes=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 312, + "top": 323, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGArRJpHmtvCes=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGArRJpHmtxV6I=", + "_parent": { + "$ref": "AAAAAAGArRJpHmtvCes=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 312, + "top": 308, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGArRJpHmtvCes=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGArRJpHmty1a4=", + "_parent": { + "$ref": "AAAAAAGArRJpHmtvCes=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 312, + "top": 353, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGArRJpHmtvCes=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAXjxqhKVg3/0=" + }, + "tail": { + "$ref": "AAAAAAGAt2B/j8sCBrY=" + }, + "points": "312:308;312:344;360:344", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGArRJpHmtwCyE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGArRJpHmtxV6I=" + }, + "propertyLabel": { + "$ref": "AAAAAAGArRJpHmty1a4=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGAt2B/j8sCBrY=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAt2B/jcsAIYY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGAt2B/j8sDh1w=", + "_parent": { + "$ref": "AAAAAAGAt2B/j8sCBrY=" + }, + "model": { + "$ref": "AAAAAAGAt2B/jcsAIYY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGAt2B/j8sEuwk=", + "_parent": { + "$ref": "AAAAAAGAt2B/j8sDh1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 464, + "top": -40, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAt2B/kMsFs+A=", + "_parent": { + "$ref": "AAAAAAGAt2B/j8sDh1w=" + }, + "font": "Arial;13;1", + "left": 261, + "top": 271, + "width": 55.376953125, + "height": 13, + "text": "Game" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAt2B/kMsGFZ4=", + "_parent": { + "$ref": "AAAAAAGAt2B/j8sDh1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 464, + "top": -40, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAt2B/kMsHijc=", + "_parent": { + "$ref": "AAAAAAGAt2B/j8sDh1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 464, + "top": -40, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 256, + "top": 264, + "width": 65.376953125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGAt2B/j8sEuwk=" + }, + "nameLabel": { + "$ref": "AAAAAAGAt2B/kMsFs+A=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGAt2B/kMsGFZ4=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAt2B/kMsHijc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGAt2B/kMsIO4k=", + "_parent": { + "$ref": "AAAAAAGAt2B/j8sCBrY=" + }, + "model": { + "$ref": "AAAAAAGAt2B/jcsAIYY=" + }, + "font": "Arial;13;0", + "left": 256, + "top": 289, + "width": 65.376953125, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGAt2B/kMsJS6Y=", + "_parent": { + "$ref": "AAAAAAGAt2B/j8sCBrY=" + }, + "model": { + "$ref": "AAAAAAGAt2B/jcsAIYY=" + }, + "font": "Arial;13;0", + "left": 256, + "top": 299, + "width": 65.376953125, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGAt2B/kMsKJ+s=", + "_parent": { + "$ref": "AAAAAAGAt2B/j8sCBrY=" + }, + "model": { + "$ref": "AAAAAAGAt2B/jcsAIYY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 232, + "top": -20, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGAt2B/kMsLB88=", + "_parent": { + "$ref": "AAAAAAGAt2B/j8sCBrY=" + }, + "model": { + "$ref": "AAAAAAGAt2B/jcsAIYY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 232, + "top": -20, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 256, + "top": 264, + "width": 65.376953125, + "height": 45, + "nameCompartment": { + "$ref": "AAAAAAGAt2B/j8sDh1w=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGAt2B/kMsIO4k=" + }, + "operationCompartment": { + "$ref": "AAAAAAGAt2B/kMsJS6Y=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGAt2B/kMsKJ+s=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGAt2B/kMsLB88=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAGAt2CDMMt2ZWE=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAt2CDMMt0Z9w=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAt2CDMMt3Kec=", + "_parent": { + "$ref": "AAAAAAGAt2CDMMt2ZWE=" + }, + "model": { + "$ref": "AAAAAAGAt2CDMMt0Z9w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 246, + "top": 240, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGAt2CDMMt2ZWE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAt2CDMct4NTs=", + "_parent": { + "$ref": "AAAAAAGAt2CDMMt2ZWE=" + }, + "model": { + "$ref": "AAAAAAGAt2CDMMt0Z9w=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 233, + "top": 248, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGAt2CDMMt2ZWE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAt2CDMct5uM8=", + "_parent": { + "$ref": "AAAAAAGAt2CDMMt2ZWE=" + }, + "model": { + "$ref": "AAAAAAGAt2CDMMt0Z9w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 271, + "top": 225, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGAt2CDMMt2ZWE=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAk4i0r6t962o=" + }, + "tail": { + "$ref": "AAAAAAGAt2B/j8sCBrY=" + }, + "lineStyle": 1, + "points": "274:263;245:215", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGAt2CDMMt3Kec=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGAt2CDMct4NTs=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAt2CDMct5uM8=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGAt2yrkdd/S50=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAt2yrkNd9c4Q=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGAt2yrkdeAgTs=", + "_parent": { + "$ref": "AAAAAAGAt2yrkdd/S50=" + }, + "model": { + "$ref": "AAAAAAGAt2yrkNd9c4Q=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGAt2yrkdeBr7Y=", + "_parent": { + "$ref": "AAAAAAGAt2yrkdeAgTs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": -986, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAt2yrkdeCijs=", + "_parent": { + "$ref": "AAAAAAGAt2yrkdeAgTs=" + }, + "font": "Arial;13;1", + "left": 605, + "top": 23, + "width": 394.18310546875, + "height": 13, + "text": "SoundControler" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAt2yrkdeDCKI=", + "_parent": { + "$ref": "AAAAAAGAt2yrkdeAgTs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": -986, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAt2yrkdeEDYI=", + "_parent": { + "$ref": "AAAAAAGAt2yrkdeAgTs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": -986, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 600, + "top": 16, + "width": 404.18310546875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGAt2yrkdeBr7Y=" + }, + "nameLabel": { + "$ref": "AAAAAAGAt2yrkdeCijs=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGAt2yrkdeDCKI=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAt2yrkdeEDYI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGAt2yrkdeFILA=", + "_parent": { + "$ref": "AAAAAAGAt2yrkdd/S50=" + }, + "model": { + "$ref": "AAAAAAGAt2yrkNd9c4Q=" + }, + "font": "Arial;13;0", + "left": 600, + "top": 41, + "width": 404.18310546875, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGAt2yrkdeGDUM=", + "_parent": { + "$ref": "AAAAAAGAt2yrkdd/S50=" + }, + "model": { + "$ref": "AAAAAAGAt2yrkNd9c4Q=" + }, + "subViews": [ + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAt21f4ujnQ7g=", + "_parent": { + "$ref": "AAAAAAGAt2yrkdeGDUM=" + }, + "model": { + "$ref": "AAAAAAGAt21fvOjVin0=" + }, + "font": "Arial;13;0", + "left": 605, + "top": 56, + "width": 394.18310546875, + "height": 13, + "text": "+player_music(music_path: Str, volume: Float): None", + "horizontalAlignment": 0 + }, + { + "_type": "UMLOperationView", + "_id": "AAAAAAGAt22r4em0kdw=", + "_parent": { + "$ref": "AAAAAAGAt2yrkdeGDUM=" + }, + "model": { + "$ref": "AAAAAAGAt22rxemimug=" + }, + "font": "Arial;13;0", + "left": 605, + "top": 71, + "width": 394.18310546875, + "height": 13, + "text": "+player_sound(sound_path: Str, volume: Float, max_time: Int): None", + "horizontalAlignment": 0 + } + ], + "font": "Arial;13;0", + "left": 600, + "top": 51, + "width": 404.18310546875, + "height": 38 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGAt2yrkdeHO1k=", + "_parent": { + "$ref": "AAAAAAGAt2yrkdd/S50=" + }, + "model": { + "$ref": "AAAAAAGAt2yrkNd9c4Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": -493, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGAt2yrkdeIQ+8=", + "_parent": { + "$ref": "AAAAAAGAt2yrkdd/S50=" + }, + "model": { + "$ref": "AAAAAAGAt2yrkNd9c4Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": -493, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 600, + "top": 16, + "width": 404.18310546875, + "height": 73, + "nameCompartment": { + "$ref": "AAAAAAGAt2yrkdeAgTs=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGAt2yrkdeFILA=" + }, + "operationCompartment": { + "$ref": "AAAAAAGAt2yrkdeGDUM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGAt2yrkdeHO1k=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGAt2yrkdeIQ+8=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGAux1Tbu7gIiM=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAux1Tbe7ewXU=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGAux1Tbu7hkco=", + "_parent": { + "$ref": "AAAAAAGAux1Tbu7gIiM=" + }, + "model": { + "$ref": "AAAAAAGAux1Tbe7ewXU=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGAux1Tbu7iqmA=", + "_parent": { + "$ref": "AAAAAAGAux1Tbu7hkco=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 97.4150390625, + "top": -64, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAux1Tb+7jxoQ=", + "_parent": { + "$ref": "AAAAAAGAux1Tbu7hkco=" + }, + "font": "Arial;13;1", + "left": 821, + "top": 359, + "width": 70.05908203125, + "height": 13, + "text": "BattleMode" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAux1Tb+7kIqY=", + "_parent": { + "$ref": "AAAAAAGAux1Tbu7hkco=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 97.4150390625, + "top": -64, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGAux1Tb+7lW9A=", + "_parent": { + "$ref": "AAAAAAGAux1Tbu7hkco=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 97.4150390625, + "top": -64, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 816, + "top": 352, + "width": 80.05908203125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGAux1Tbu7iqmA=" + }, + "nameLabel": { + "$ref": "AAAAAAGAux1Tb+7jxoQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGAux1Tb+7kIqY=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAux1Tb+7lW9A=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGAux1Tb+7mkiQ=", + "_parent": { + "$ref": "AAAAAAGAux1Tbu7gIiM=" + }, + "model": { + "$ref": "AAAAAAGAux1Tbe7ewXU=" + }, + "font": "Arial;13;0", + "left": 816, + "top": 377, + "width": 80.05908203125, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGAux1Tb+7nlpE=", + "_parent": { + "$ref": "AAAAAAGAux1Tbu7gIiM=" + }, + "model": { + "$ref": "AAAAAAGAux1Tbe7ewXU=" + }, + "font": "Arial;13;0", + "left": 816, + "top": 387, + "width": 80.05908203125, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGAux1Tb+7oIbk=", + "_parent": { + "$ref": "AAAAAAGAux1Tbu7gIiM=" + }, + "model": { + "$ref": "AAAAAAGAux1Tbe7ewXU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 48.70751953125, + "top": -32, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGAux1Tb+7peBE=", + "_parent": { + "$ref": "AAAAAAGAux1Tbu7gIiM=" + }, + "model": { + "$ref": "AAAAAAGAux1Tbe7ewXU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 48.70751953125, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 816, + "top": 352, + "width": 80.05908203125, + "height": 45, + "nameCompartment": { + "$ref": "AAAAAAGAux1Tbu7hkco=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGAux1Tb+7mkiQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAGAux1Tb+7nlpE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGAux1Tb+7oIbk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGAux1Tb+7peBE=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAGAux1WsO9jHLk=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGAux1Wr+9hCM4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAux1WsO9kFRQ=", + "_parent": { + "$ref": "AAAAAAGAux1WsO9jHLk=" + }, + "model": { + "$ref": "AAAAAAGAux1Wr+9hCM4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 783, + "top": 353, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGAux1WsO9jHLk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAux1WsO9l69Y=", + "_parent": { + "$ref": "AAAAAAGAux1WsO9jHLk=" + }, + "model": { + "$ref": "AAAAAAGAux1Wr+9hCM4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 777, + "top": 367, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGAux1WsO9jHLk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGAux1WsO9mhi4=", + "_parent": { + "$ref": "AAAAAAGAux1WsO9jHLk=" + }, + "model": { + "$ref": "AAAAAAGAux1Wr+9hCM4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 794, + "top": 326, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGAux1WsO9jHLk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAXjxqhKVg3/0=" + }, + "tail": { + "$ref": "AAAAAAGAux1Tbu7gIiM=" + }, + "lineStyle": 1, + "points": "815:357;764:336", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGAux1WsO9kFRQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGAux1WsO9l69Y=" + }, + "propertyLabel": { + "$ref": "AAAAAAGAux1WsO9mhi4=" + } + }, + { + "_type": "UMLDependencyView", + "_id": "AAAAAAGA2rKzngQloLo=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2rKzngQmj90=", + "_parent": { + "$ref": "AAAAAAGA2rKzngQloLo=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 902, + "top": 233, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGA2rKzngQloLo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2rKzngQnQVo=", + "_parent": { + "$ref": "AAAAAAGA2rKzngQloLo=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 917, + "top": 233, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGA2rKzngQloLo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2rKzngQoFJY=", + "_parent": { + "$ref": "AAAAAAGA2rKzngQloLo=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 872, + "top": 234, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGA2rKzngQloLo=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAux1Tbu7gIiM=" + }, + "tail": { + "$ref": "AAAAAAGAl12L1ka5A8Q=" + }, + "points": "1024:240;887:240;887:352", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGA2rKzngQmj90=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGA2rKzngQnQVo=" + }, + "propertyLabel": { + "$ref": "AAAAAAGA2rKzngQoFJY=" + } + }, + { + "_type": "UMLDependencyView", + "_id": "AAAAAAGA2rOQ8REXCjk=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2rOQ8REYFRw=", + "_parent": { + "$ref": "AAAAAAGA2rOQ8REXCjk=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 296, + "top": 531, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGA2rOQ8REXCjk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2rOQ8REZpO0=", + "_parent": { + "$ref": "AAAAAAGA2rOQ8REXCjk=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 296, + "top": 516, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGA2rOQ8REXCjk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2rOQ8REauMs=", + "_parent": { + "$ref": "AAAAAAGA2rOQ8REXCjk=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 296, + "top": 561, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGA2rOQ8REXCjk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAk4Bm7aZpz/0=" + }, + "tail": { + "$ref": "AAAAAAGAl441S8CcU7A=" + }, + "points": "296:560;296:552;576:552", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGA2rOQ8REYFRw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGA2rOQ8REZpO0=" + }, + "propertyLabel": { + "$ref": "AAAAAAGA2rOQ8REauMs=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGA2rRtGhaVeJg=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGA2rRtGRaTuHc=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGA2rRtGhaW0l8=", + "_parent": { + "$ref": "AAAAAAGA2rRtGhaVeJg=" + }, + "model": { + "$ref": "AAAAAAGA2rRtGRaTuHc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGA2rRtGhaX2KU=", + "_parent": { + "$ref": "AAAAAAGA2rRtGhaW0l8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 336, + "top": -120, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGA2rRtGxaYLvE=", + "_parent": { + "$ref": "AAAAAAGA2rRtGhaW0l8=" + }, + "font": "Arial;13;1", + "left": 853, + "top": 535, + "width": 41.919921875, + "height": 13, + "text": "Bullet" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGA2rRtGxaZs6E=", + "_parent": { + "$ref": "AAAAAAGA2rRtGhaW0l8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 336, + "top": -120, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGA2rRtGxaatfQ=", + "_parent": { + "$ref": "AAAAAAGA2rRtGhaW0l8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 336, + "top": -120, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 848, + "top": 528, + "width": 51.919921875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGA2rRtGhaX2KU=" + }, + "nameLabel": { + "$ref": "AAAAAAGA2rRtGxaYLvE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGA2rRtGxaZs6E=" + }, + "propertyLabel": { + "$ref": "AAAAAAGA2rRtGxaatfQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGA2rRtGxabAsU=", + "_parent": { + "$ref": "AAAAAAGA2rRtGhaVeJg=" + }, + "model": { + "$ref": "AAAAAAGA2rRtGRaTuHc=" + }, + "font": "Arial;13;0", + "left": 848, + "top": 553, + "width": 51.919921875, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGA2rRtGxacCOU=", + "_parent": { + "$ref": "AAAAAAGA2rRtGhaVeJg=" + }, + "model": { + "$ref": "AAAAAAGA2rRtGRaTuHc=" + }, + "font": "Arial;13;0", + "left": 848, + "top": 563, + "width": 51.919921875, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGA2rRtGxad/Q8=", + "_parent": { + "$ref": "AAAAAAGA2rRtGhaVeJg=" + }, + "model": { + "$ref": "AAAAAAGA2rRtGRaTuHc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 168, + "top": -60, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGA2rRtGxaeC6g=", + "_parent": { + "$ref": "AAAAAAGA2rRtGhaVeJg=" + }, + "model": { + "$ref": "AAAAAAGA2rRtGRaTuHc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 168, + "top": -60, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 848, + "top": 528, + "width": 51.919921875, + "height": 45, + "nameCompartment": { + "$ref": "AAAAAAGA2rRtGhaW0l8=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGA2rRtGxabAsU=" + }, + "operationCompartment": { + "$ref": "AAAAAAGA2rRtGxacCOU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGA2rRtGxad/Q8=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGA2rRtGxaeC6g=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAGA2rRwnxbrA3w=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGA2rRwnxbpX48=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2rRwoBbsuqk=", + "_parent": { + "$ref": "AAAAAAGA2rRwnxbrA3w=" + }, + "model": { + "$ref": "AAAAAAGA2rRwnxbpX48=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 842, + "top": 620, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGA2rRwnxbrA3w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2rRwoBbtwRc=", + "_parent": { + "$ref": "AAAAAAGA2rRwnxbrA3w=" + }, + "model": { + "$ref": "AAAAAAGA2rRwnxbpX48=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 827, + "top": 617, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGA2rRwnxbrA3w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2rRwoBbuetw=", + "_parent": { + "$ref": "AAAAAAGA2rRwnxbrA3w=" + }, + "model": { + "$ref": "AAAAAAGA2rRwnxbpX48=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 871, + "top": 627, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGA2rRwnxbrA3w=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGA2rRtGhaVeJg=" + }, + "tail": { + "$ref": "AAAAAAGArBbN0/ToEwE=" + }, + "lineStyle": 1, + "points": "846:687;869:573", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGA2rRwoBbsuqk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGA2rRwoBbtwRc=" + }, + "propertyLabel": { + "$ref": "AAAAAAGA2rRwoBbuetw=" + } + }, + { + "_type": "UMLDependencyView", + "_id": "AAAAAAGA2rTdbxm5yuo=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2rTdbxm6lGE=", + "_parent": { + "$ref": "AAAAAAGA2rTdbxm5yuo=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 880, + "top": 505, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGA2rTdbxm5yuo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2rTdbxm79h8=", + "_parent": { + "$ref": "AAAAAAGA2rTdbxm5yuo=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 880, + "top": 520, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGA2rTdbxm5yuo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2rTdbxm8i5w=", + "_parent": { + "$ref": "AAAAAAGA2rTdbxm5yuo=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 881, + "top": 475, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGA2rTdbxm5yuo=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAk4Bm7aZpz/0=" + }, + "tail": { + "$ref": "AAAAAAGA2rRtGhaVeJg=" + }, + "points": "881:528;881:496;765:496", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGA2rTdbxm6lGE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGA2rTdbxm79h8=" + }, + "propertyLabel": { + "$ref": "AAAAAAGA2rTdbxm8i5w=" + } + }, + { + "_type": "UMLDependencyView", + "_id": "AAAAAAGA2r5nhyxk8B8=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2r5nhyxlR7o=", + "_parent": { + "$ref": "AAAAAAGA2r5nhyxk8B8=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 454, + "top": 41, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGA2r5nhyxk8B8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2r5nhyxmqqI=", + "_parent": { + "$ref": "AAAAAAGA2r5nhyxk8B8=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 469, + "top": 41, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGA2r5nhyxk8B8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2r5nhyxn+Pc=", + "_parent": { + "$ref": "AAAAAAGA2r5nhyxk8B8=" + }, + "model": { + "$ref": "AAAAAAGArRJpHWtt8EM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 425, + "top": 42, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGA2r5nhyxk8B8=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAXjxqhKVg3/0=" + }, + "tail": { + "$ref": "AAAAAAGAt2yrkdd/S50=" + }, + "points": "600:48;440:48;440:96", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGA2r5nhyxlR7o=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGA2r5nhyxmqqI=" + }, + "propertyLabel": { + "$ref": "AAAAAAGA2r5nhyxn+Pc=" + } + }, + { + "_type": "UMLClassView", + "_id": "AAAAAAGA2r8tmS9PRnY=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGA2r8tmC9NiKo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAGA2r8tmS9QQ5o=", + "_parent": { + "$ref": "AAAAAAGA2r8tmS9PRnY=" + }, + "model": { + "$ref": "AAAAAAGA2r8tmC9NiKo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAGA2r8tmS9RiAU=", + "_parent": { + "$ref": "AAAAAAGA2r8tmS9QQ5o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": -60, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAGA2r8tmS9SdB8=", + "_parent": { + "$ref": "AAAAAAGA2r8tmS9QQ5o=" + }, + "font": "Arial;13;1", + "left": 805, + "top": 135, + "width": 128.3115234375, + "height": 13, + "text": "TankSoundControler" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGA2r8tmS9THCA=", + "_parent": { + "$ref": "AAAAAAGA2r8tmS9QQ5o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": -60, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAGA2r8tmS9UZfo=", + "_parent": { + "$ref": "AAAAAAGA2r8tmS9QQ5o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": -60, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 800, + "top": 128, + "width": 138.3115234375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAGA2r8tmS9RiAU=" + }, + "nameLabel": { + "$ref": "AAAAAAGA2r8tmS9SdB8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAGA2r8tmS9THCA=" + }, + "propertyLabel": { + "$ref": "AAAAAAGA2r8tmS9UZfo=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAGA2r8tmS9VnwQ=", + "_parent": { + "$ref": "AAAAAAGA2r8tmS9PRnY=" + }, + "model": { + "$ref": "AAAAAAGA2r8tmC9NiKo=" + }, + "font": "Arial;13;0", + "left": 800, + "top": 153, + "width": 138.3115234375, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAGA2r8tmS9WUE8=", + "_parent": { + "$ref": "AAAAAAGA2r8tmS9PRnY=" + }, + "model": { + "$ref": "AAAAAAGA2r8tmC9NiKo=" + }, + "font": "Arial;13;0", + "left": 800, + "top": 163, + "width": 138.3115234375, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAGA2r8tmS9XWhw=", + "_parent": { + "$ref": "AAAAAAGA2r8tmS9PRnY=" + }, + "model": { + "$ref": "AAAAAAGA2r8tmC9NiKo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": -30, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAGA2r8tmS9YpNY=", + "_parent": { + "$ref": "AAAAAAGA2r8tmS9PRnY=" + }, + "model": { + "$ref": "AAAAAAGA2r8tmC9NiKo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": -30, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 800, + "top": 128, + "width": 138.3115234375, + "height": 45, + "nameCompartment": { + "$ref": "AAAAAAGA2r8tmS9QQ5o=" + }, + "attributeCompartment": { + "$ref": "AAAAAAGA2r8tmS9VnwQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAGA2r8tmS9WUE8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAGA2r8tmS9XWhw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAGA2r8tmS9YpNY=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAGA2r8xtC+HpCc=", + "_parent": { + "$ref": "AAAAAAFF+qBtyKM79qY=" + }, + "model": { + "$ref": "AAAAAAGA2r8xtC+FTUY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2r8xtC+Igus=", + "_parent": { + "$ref": "AAAAAAGA2r8xtC+HpCc=" + }, + "model": { + "$ref": "AAAAAAGA2r8xtC+FTUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 826, + "top": 110, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGA2r8xtC+HpCc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2r8xtC+JLmY=", + "_parent": { + "$ref": "AAAAAAGA2r8xtC+HpCc=" + }, + "model": { + "$ref": "AAAAAAGA2r8xtC+FTUY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 814, + "top": 118, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAGA2r8xtC+HpCc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAGA2r8xtC+KvpY=", + "_parent": { + "$ref": "AAAAAAGA2r8xtC+HpCc=" + }, + "model": { + "$ref": "AAAAAAGA2r8xtC+FTUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 851, + "top": 93, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAGA2r8xtC+HpCc=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAGAt2yrkdd/S50=" + }, + "tail": { + "$ref": "AAAAAAGA2r8tmS9PRnY=" + }, + "lineStyle": 1, + "points": "852:127;826:89", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAGA2r8xtC+Igus=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAGA2r8xtC+JLmY=" + }, + "propertyLabel": { + "$ref": "AAAAAAGA2r8xtC+KvpY=" + } + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAXjxqgqVefzo=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "GameMode", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAGAk4BnNKaQwu4=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAk4BnNKaRqgE=", + "_parent": { + "$ref": "AAAAAAGAk4BnNKaQwu4=" + }, + "reference": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "aggregation": "shared" + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAk4BnNKaS5fU=", + "_parent": { + "$ref": "AAAAAAGAk4BnNKaQwu4=" + }, + "reference": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + } + } + }, + { + "_type": "UMLGeneralization", + "_id": "AAAAAAGAk4i1pKuzgtg=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "source": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "target": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAGAk49dULqoMoU=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAk49dULqprL4=", + "_parent": { + "$ref": "AAAAAAGAk49dULqoMoU=" + }, + "reference": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "aggregation": "shared" + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAk49dULqqDTk=", + "_parent": { + "$ref": "AAAAAAGAk49dULqoMoU=" + }, + "reference": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAGAk6cYod/xDsc=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAk6cYod/yqTQ=", + "_parent": { + "$ref": "AAAAAAGAk6cYod/xDsc=" + }, + "reference": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "aggregation": "shared" + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAk6cYod/zYlk=", + "_parent": { + "$ref": "AAAAAAGAk6cYod/xDsc=" + }, + "reference": { + "$ref": "AAAAAAGAk6cYDd+5W4E=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAGAk6eoNOFRg2c=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAk6eoNOFSc58=", + "_parent": { + "$ref": "AAAAAAGAk6eoNOFRg2c=" + }, + "reference": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "aggregation": "shared" + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAk6eoNOFTh3E=", + "_parent": { + "$ref": "AAAAAAGAk6eoNOFRg2c=" + }, + "reference": { + "$ref": "AAAAAAGAk6enhOEK5m0=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAGAlv9NBkqd3Qg=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAlv9NBkqehx4=", + "_parent": { + "$ref": "AAAAAAGAlv9NBkqd3Qg=" + }, + "reference": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "aggregation": "shared" + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAlv9NBkqfwcg=", + "_parent": { + "$ref": "AAAAAAGAlv9NBkqd3Qg=" + }, + "reference": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAGAlw1bZIsuXy4=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAlw1bZIsvXas=", + "_parent": { + "$ref": "AAAAAAGAlw1bZIsuXy4=" + }, + "reference": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "aggregation": "shared" + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAlw1bZIsw4Ks=", + "_parent": { + "$ref": "AAAAAAGAlw1bZIsuXy4=" + }, + "reference": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAGAl57vqBbm3Ro=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAl57vqBbn1Y8=", + "_parent": { + "$ref": "AAAAAAGAl57vqBbm3Ro=" + }, + "reference": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "aggregation": "shared" + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAl57vqBbo+Ck=", + "_parent": { + "$ref": "AAAAAAGAl57vqBbm3Ro=" + }, + "reference": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAGAt2yu69fxX14=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAt2yu69fyJ1s=", + "_parent": { + "$ref": "AAAAAAGAt2yu69fxX14=" + }, + "reference": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "aggregation": "shared" + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAt2yu69fzZFY=", + "_parent": { + "$ref": "AAAAAAGAt2yu69fxX14=" + }, + "reference": { + "$ref": "AAAAAAGAt2yrkNd9c4Q=" + } + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk0r8lqXMu2M=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "all_sprites", + "type": "Group" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAXj2LaKWObGk=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "bullets", + "type": "Group" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk3nQ0KYmHrg=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "walls", + "type": "Group" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk3yvZqZCZa4=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "mobs", + "type": "Group" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk28mGKYPh40=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "player_1P", + "type": "Sprite" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk2WvwaYITAc=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "is_paused", + "type": "Bool" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk3fk+KYW84M=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "is_playing", + "type": "Bool" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk3hGkKYe19M=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "is_sound", + "type": "Bool" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk2Un6KYBvzo=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "used_frame", + "type": "Int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAmBTs57dfR+A=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "frame_limit", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk3qQUqYtB2U=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "window", + "type": "pygame.Surface" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl1t4D0O8V40=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "map", + "type": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + } + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAmAyRvVDTY88=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "state", + "type": "Str" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAmAzqn1QpDMk=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "status", + "type": "str" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk15Ly6XULl4=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "__init__", + "visibility": "private", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk4MoKaeAjcY=", + "_parent": { + "$ref": "AAAAAAGAk15Ly6XULl4=" + }, + "name": "map_path", + "type": "Str" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk4MoL6eBWV4=", + "_parent": { + "$ref": "AAAAAAGAk15Ly6XULl4=" + }, + "name": "time_limit", + "type": "Int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk4P1uKeR7m4=", + "_parent": { + "$ref": "AAAAAAGAk15Ly6XULl4=" + }, + "name": "sound", + "type": "Bool" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk7kYswkcTw4=", + "_parent": { + "$ref": "AAAAAAGAk15Ly6XULl4=" + }, + "type": "None", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk1709KXc5+4=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "get_result", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk7lJigl/D5A=", + "_parent": { + "$ref": "AAAAAAGAk1709KXc5+4=" + }, + "type": "Dict", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk1894KXkSJ8=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "updata", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk4STn6i5rCw=", + "_parent": { + "$ref": "AAAAAAGAk1894KXkSJ8=" + }, + "name": "command", + "type": "Dict" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk7ll4wni+6E=", + "_parent": { + "$ref": "AAAAAAGAk1894KXkSJ8=" + }, + "type": "None", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk2Bn7qXt7o8=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "check_events", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk7l76gpF308=", + "_parent": { + "$ref": "AAAAAAGAk2Bn7qXt7o8=" + }, + "type": "None", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk2DZMqX0aQQ=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "check_collisions", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk7mjUQqoCa4=", + "_parent": { + "$ref": "AAAAAAGAk2DZMqX0aQQ=" + }, + "type": "None", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAmBa4jbpw4xo=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "reset", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAmBkSOr8wht8=", + "_parent": { + "$ref": "AAAAAAGAmBa4jbpw4xo=" + }, + "type": "tuple", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAtcd3+p02Ti8=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "draw_sprite_data" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAtcf9QKFmM8o=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "create_init_image_data" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAtcgr7KVa4xs=", + "_parent": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "name": "draw_text_data" + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAXlNOraWdYtA=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "BattleMode" + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAk4Bm7aZnfh4=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "BattleMode", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAGAl442pcD/AMA=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAl442pcEA4c0=", + "_parent": { + "$ref": "AAAAAAGAl442pcD/AMA=" + }, + "reference": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "aggregation": "shared" + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAl442pcEBQxY=", + "_parent": { + "$ref": "AAAAAAGAl442pcD/AMA=" + }, + "reference": { + "$ref": "AAAAAAGAl441S8CaKhY=" + } + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk4VFJajrfOU=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "name": "player_2P", + "type": "sprite" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl1ODLSYTr98=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "name": "is_invincible", + "type": "Bool" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl1PKaSpLQKM=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "name": "is_through_wall", + "type": "Bool" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl1aZlTOYSFU=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "name": "is_debug", + "type": "Bool" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAmCsj48vzQzY=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "name": "players", + "type": "Group" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAmCtP1szA3Lk=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "name": "walls", + "type": "Group" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAmCt9Oc2xkSk=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "name": "bullets", + "type": "Group" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAmCu0Q86iDIA=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "name": "player_1P", + "type": "sprite" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAGAq751PONGLwk=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "name": "create_bullte", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAq79ZKePvrbE=", + "_parent": { + "$ref": "AAAAAAGAq751PONGLwk=" + }, + "name": "shoot_info", + "type": "Dict" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAtepAErCzCDo=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "name": "draw_sprite_data", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAtep5lrFB8L4=", + "_parent": { + "$ref": "AAAAAAGAtepAErCzCDo=" + }, + "type": "list", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAtep9JrFwneU=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "name": "create_init_image_data", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAteq0S7Icles=", + "_parent": { + "$ref": "AAAAAAGAtep9JrFwneU=" + }, + "type": "list", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAteq3xbJLFFI=", + "_parent": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "name": "draw_text_data", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAter5rrMzGxc=", + "_parent": { + "$ref": "AAAAAAGAteq3xbJLFFI=" + }, + "type": "list", + "direction": "return" + } + ] + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAk4i0rqt7zy4=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "MyGame", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAGAk4y3WK4ALvo=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAk4y3WK4BatA=", + "_parent": { + "$ref": "AAAAAAGAk4y3WK4ALvo=" + }, + "reference": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + } + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAk4y3WK4ClmQ=", + "_parent": { + "$ref": "AAAAAAGAk4y3WK4ALvo=" + }, + "reference": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "aggregation": "shared" + } + }, + { + "_type": "UMLGeneralization", + "_id": "AAAAAAGAk5DXmsJevOw=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "source": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "target": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAGAl012qu/x7Ck=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAl012qu/yLn4=", + "_parent": { + "$ref": "AAAAAAGAl012qu/x7Ck=" + }, + "reference": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + } + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAl012qu/zDiE=", + "_parent": { + "$ref": "AAAAAAGAl012qu/x7Ck=" + }, + "reference": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAGAl1AtTfpwcuU=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAl1AtTfpxYF0=", + "_parent": { + "$ref": "AAAAAAGAl1AtTfpwcuU=" + }, + "reference": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + } + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAGAl1AtTfpyJbg=", + "_parent": { + "$ref": "AAAAAAGAl1AtTfpwcuU=" + }, + "reference": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + } + } + }, + { + "_type": "UMLDependency", + "_id": "AAAAAAGArRJpHWtt8EM=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "source": { + "$ref": "AAAAAAGAt2yrkNd9c4Q=" + }, + "target": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlvY38TFLyd8=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "name": "scene", + "type": "Scene" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk4kf+KyVMfg=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "name": "attachements", + "type": "List" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk4l896y9t7w=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "name": "game_mode", + "type": "Q" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk4qz3azr1dY=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "name": "sound", + "type": "Str" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk4uV6a0Zir8=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "name": "map_path", + "type": "Str" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAGAlvcFRzJ2WKg=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "name": "__init__", + "visibility": "private", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAlvdZ9DKzID8=", + "_parent": { + "$ref": "AAAAAAGAlvcFRzJ2WKg=" + }, + "name": "map_no", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGAlvdZ9DK0nsQ=", + "_parent": { + "$ref": "AAAAAAGAlvcFRzJ2WKg=" + }, + "name": "sound", + "type": "str" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk5zhAtNMoaw=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "name": "get_scene_info", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk6Gk29qFbgk=", + "_parent": { + "$ref": "AAAAAAGAk5zhAtNMoaw=" + }, + "type": "Dict", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk52n3dPyZ8c=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "name": "is_running", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk6HPK9rxn3M=", + "_parent": { + "$ref": "AAAAAAGAk52n3dPyZ8c=" + }, + "type": "Bool", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk54nv9Q7Idw=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "name": "set_game_mode", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk6JuY9u3Yeo=", + "_parent": { + "$ref": "AAAAAAGAk54nv9Q7Idw=" + }, + "name": "game_path", + "type": "Str" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk6JuY9u4GK4=", + "_parent": { + "$ref": "AAAAAAGAk54nv9Q7Idw=" + }, + "type": "Q", + "direction": "return" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk7STMvrR3ow=", + "_parent": { + "$ref": "AAAAAAGAk54nv9Q7Idw=" + }, + "name": "is_sound", + "type": "Bool" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk6KdVtwW3yQ=", + "_parent": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + }, + "name": "rank", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk6L7nt0lQpE=", + "_parent": { + "$ref": "AAAAAAGAk6KdVtwW3yQ=" + }, + "type": "List", + "direction": "return" + } + ] + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAk4y2+q3IC28=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Class1" + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAk49c4rpw7bU=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Class2" + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAk5CJRb/kl10=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Class3", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAGAk5CJqcAr7io=", + "_parent": { + "$ref": "AAAAAAGAk5CJRb/kl10=" + }, + "source": { + "$ref": "AAAAAAGAk4Bm7aZnfh4=" + }, + "target": { + "$ref": "AAAAAAGAux1Tbe7ewXU=" + } + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAk5DXD8IXyNM=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "PaiaGame", + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk5G7FsRFRTg=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "name": "scene", + "type": "Scene" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk5H9QsSOiRk=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "name": "frame_count", + "type": "Int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk5I3GsTjZv4=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "name": "game_result_state", + "type": "Str" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk5W51cWqrZ4=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "name": "__init__", + "visibility": "private", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk5oEMcq8Yag=", + "_parent": { + "$ref": "AAAAAAGAk5W51cWqrZ4=" + }, + "type": "None", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk5XwpMYA/gU=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "name": "update", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk5kubsoOvlM=", + "_parent": { + "$ref": "AAAAAAGAk5XwpMYA/gU=" + }, + "type": "None", + "direction": "return" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk5nihsplpqQ=", + "_parent": { + "$ref": "AAAAAAGAk5XwpMYA/gU=" + }, + "name": "commands", + "type": "Dict" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk5a2GMciKVk=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "name": "game_to_player_data", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk5dAyMdrnfU=", + "_parent": { + "$ref": "AAAAAAGAk5a2GMciKVk=" + }, + "type": "Dict", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk5dBQsd/Tmw=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "name": "reset", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk5doDMfImGU=", + "_parent": { + "$ref": "AAAAAAGAk5dBQsd/Tmw=" + }, + "type": "None", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk5dojsfcCqM=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "name": "get_scene_init_data", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk5fDusgltxQ=", + "_parent": { + "$ref": "AAAAAAGAk5dojsfcCqM=" + }, + "type": "Dict", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk5fEMsg5d4g=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "name": "get_scene_progress_data", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk5gh+8iCscw=", + "_parent": { + "$ref": "AAAAAAGAk5fEMsg5d4g=" + }, + "type": "Dict", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk5gs7ciWGr0=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "name": "get_game_result", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk5iCDcjfyUE=", + "_parent": { + "$ref": "AAAAAAGAk5gs7ciWGr0=" + }, + "type": "Dict", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk5iCl8jzZ5c=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "name": "get_keyboard_command", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk5jVP8k8WZ8=", + "_parent": { + "$ref": "AAAAAAGAk5iCl8jzZ5c=" + }, + "type": "Dict", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk5jVvclQBvY=", + "_parent": { + "$ref": "AAAAAAGAk5DXD8IXyNM=" + }, + "name": "ai_clients", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk5kSCcmZHNw=", + "_parent": { + "$ref": "AAAAAAGAk5jVvclQBvY=" + }, + "type": "List", + "direction": "return" + } + ] + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAk6cYDd+5W4E=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "sound_controller" + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAk6enhOEK5m0=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "TankManMap", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAGAk6h3Z+igXLw=", + "_parent": { + "$ref": "AAAAAAGAk6enhOEK5m0=" + }, + "source": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + }, + "target": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + } + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAk6h2wehKJfM=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "TiledMap", + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk6urfvGImRk=", + "_parent": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + }, + "name": "width", + "type": "Int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk6vsvvHyyiw=", + "_parent": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + }, + "name": "height", + "type": "Int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAk6wt1vL1d7s=", + "_parent": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + }, + "name": "tmx_data", + "type": "pytmx.pytmx.TieldMap" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk6kr/O4CXBo=", + "_parent": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + }, + "name": "creat_img_init_data", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk6n2B+9FaUQ=", + "_parent": { + "$ref": "AAAAAAGAk6kr/O4CXBo=" + }, + "type": "List", + "direction": "return" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGAlvm10jeA4Yk=", + "_parent": { + "$ref": "AAAAAAGAk6kr/O4CXBo=" + }, + "name": "img_no_list", + "type": "List" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk6l+y+5sE9E=", + "_parent": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + }, + "name": "creat_walls_init_data", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk6nQkO7E5AY=", + "_parent": { + "$ref": "AAAAAAGAk6l+y+5sE9E=" + }, + "type": "List", + "direction": "return" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGAlvnlgDfXWRQ=", + "_parent": { + "$ref": "AAAAAAGAk6l+y+5sE9E=" + }, + "name": "walls_img_no_list", + "type": "List" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAk6pg8fCVFEY=", + "_parent": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + }, + "name": "creat_mobs_init_data", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAk6p/yPDt2MY=", + "_parent": { + "$ref": "AAAAAAGAk6pg8fCVFEY=" + }, + "type": "List", + "direction": "return" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGAlvoTRzg6oN4=", + "_parent": { + "$ref": "AAAAAAGAk6pg8fCVFEY=" + }, + "name": "mobs_img_no_list", + "type": "List" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGArQUJgl6yVkg=", + "_parent": { + "$ref": "AAAAAAGAk6h2wehKJfM=" + }, + "name": "__init__", + "visibility": "private", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGArQU2W19brcY=", + "_parent": { + "$ref": "AAAAAAGArQUJgl6yVkg=" + }, + "name": "map_no", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArQU2XF9cNDk=", + "_parent": { + "$ref": "AAAAAAGArQUJgl6yVkg=" + }, + "name": "time_limit", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArQU2XF9dLBE=", + "_parent": { + "$ref": "AAAAAAGArQUJgl6yVkg=" + }, + "name": "sound", + "type": "str" + } + ] + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAlv9MxkpWtl4=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Player", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAGAl12MsEcchKs=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "source": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "target": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlwJoZ1/tBu0=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "img_id", + "type": "str" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlwGUa13yup4=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "is_shoot", + "type": "Bool" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlwMnN2KEupU=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "is_backward", + "type": "Bool" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlwOU8WMn6Wc=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "is_forward", + "type": "Bool" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlwPf6GeKsQk=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "last_shoot_fram", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlwR9kGgtS2k=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "shoot_delay", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlwTtomxhH4o=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "shield", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlwdG1XGdV3I=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "rot", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlwdqIHJA7mw=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "rot_speed", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlwW7rW2h/mA=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "move", + "type": "List" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlwibfnTMDYs=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "surface", + "type": "Surface" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlwk/Nna1N4Q=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "Attribute1", + "type": "" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArUoSY5Bgse4=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "angle", + "type": "Float" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAGAlwn094AqVB0=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "__init__", + "visibility": "private", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAlwoyW4CdgdM=", + "_parent": { + "$ref": "AAAAAAGAlwn094AqVB0=" + }, + "name": "_no", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGAlwoyW4CeOJ0=", + "_parent": { + "$ref": "AAAAAAGAlwn094AqVB0=" + }, + "name": "x", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGAlwoyW4CfOaQ=", + "_parent": { + "$ref": "AAAAAAGAlwn094AqVB0=" + }, + "name": "y", + "type": "int" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAlwpCJoD4hM4=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "update", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAlwqLsYFrbHY=", + "_parent": { + "$ref": "AAAAAAGAlwpCJoD4hM4=" + }, + "name": "command", + "type": "Dic" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAlwqMMIGRwsA=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "act", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAlws/R4LpU3o=", + "_parent": { + "$ref": "AAAAAAGAlwqMMIGRwsA=" + }, + "name": "commands", + "type": "Dic" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAlws/04MPOTg=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "forward" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAlwthaYOyjnQ=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "backward" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAlwt+z4RV5c4=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "turn_left" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAlwuZCYT4X14=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "turn_right" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAlwwF3obhmr0=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "collide_with_walls" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAlwwt14eEiHY=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "collide_with_bullets" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAl2lm1lFgub0=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "create_shoot_info", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGArQzl6GLVb0E=", + "_parent": { + "$ref": "AAAAAAGAl2lm1lFgub0=" + }, + "type": "dict", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAl2qJGlMLItA=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "rotate" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAq8OBs+ZVm28=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "create_shoot_info", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAq8QFS+mrae8=", + "_parent": { + "$ref": "AAAAAAGAq8OBs+ZVm28=" + }, + "type": "dict", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGArUpRK5UXbhM=", + "_parent": { + "$ref": "AAAAAAGAlv9MxkpWtl4=" + }, + "name": "get_image_data", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGArUqA/5Wl3/Y=", + "_parent": { + "$ref": "AAAAAAGArUpRK5UXbhM=" + }, + "type": "dict", + "direction": "return" + } + ] + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAlw1a9IrJsQE=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Obstacle", + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlw22UY7K4Ig=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "name": "rect_ Rect" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlw3Xno92lR8=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "name": "hit_rect", + "type": "Rect" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlw4hA5BA2UQ=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "name": "pos", + "type": "Vector2" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAlw748pRCH1Q=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "name": "lives", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArBgSKQYpZa8=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "name": "_no", + "visibility": "protected", + "type": "int" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAGAlw5+s5IJsbI=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "name": "updata" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAlw67WJK1kyc=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "name": "get_position", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAl5ZQCvegTos=", + "_parent": { + "$ref": "AAAAAAGAlw67WJK1kyc=" + }, + "type": "Tuple", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGArBeO6QFjVkw=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "name": "collide_with_bullets" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGArP0eyUMoi6I=", + "_parent": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "name": "__init__", + "visibility": "private", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGArP1KvUPRorI=", + "_parent": { + "$ref": "AAAAAAGArP0eyUMoi6I=" + }, + "name": "no", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArP1KvUPSvJE=", + "_parent": { + "$ref": "AAAAAAGArP0eyUMoi6I=" + }, + "name": "x", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArP1KvkPT9fE=", + "_parent": { + "$ref": "AAAAAAGArP0eyUMoi6I=" + }, + "name": "y", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArP1KvkPUaes=", + "_parent": { + "$ref": "AAAAAAGArP0eyUMoi6I=" + }, + "name": "width", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArP1KvkPVPY8=", + "_parent": { + "$ref": "AAAAAAGArP0eyUMoi6I=" + }, + "name": "height", + "type": "int" + } + ] + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAl012Du99Xks=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Class4" + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAl1Asv/oLieY=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Class5" + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAl12L1ka3Ntc=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Player", + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl3x7tYZrEgc=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "hit_rect", + "type": "pygame.Rect" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl31Nc4jZfC8=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "img_path", + "type": "str" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl34Jtou/xeM=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "player_info", + "type": "Dict" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl3/i6ZX1W/I=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "result_info", + "type": "Dict" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl4FjaZjP9Js=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "pos", + "type": "Vector2" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl4L7QJu261g=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "rect", + "type": "pygame.Rect" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl4VhZ53EuA8=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "score", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl4Wdu6AacQY=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "speed", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl4hBwaQ2YAk=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "used_frame", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl4gFNKIok+Q=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "is_alive", + "type": "Bool" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl4h44qaYN9Y=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "vel", + "type": "Vector2" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAmGGmHNceHdk=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "_no", + "visibility": "protected", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArT+nLob0qfY=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "image_data", + "type": "dict" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAGAl4kQlqn3uu8=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "update", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAl4kbWapqdIo=", + "_parent": { + "$ref": "AAAAAAGAl4kQlqn3uu8=" + }, + "name": "command", + "type": "Dic" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAl4qWLbKs5LA=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "act", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAl4qe0bMfDWw=", + "_parent": { + "$ref": "AAAAAAGAl4qWLbKs5LA=" + }, + "name": "commands", + "type": "Dic" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAl4nZw6wTnwM=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "get_info", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAl4npN6yGzBQ=", + "_parent": { + "$ref": "AAAAAAGAl4nZw6wTnwM=" + }, + "type": "Dict", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAl4onB65HF+4=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "get_result", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAl4ouRq66AiQ=", + "_parent": { + "$ref": "AAAAAAGAl4onB65HF+4=" + }, + "type": "Dict", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAl4wLGLXqvNE=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "get_position", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAl40Oyrqv7II=", + "_parent": { + "$ref": "AAAAAAGAl4wLGLXqvNE=" + }, + "type": "Tuple", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAl4x9obg0ows=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "player_init_data", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAl4zmhLmk57E=", + "_parent": { + "$ref": "AAAAAAGAl4x9obg0ows=" + }, + "type": "Dict", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGArT0E5nwq/LE=", + "_parent": { + "$ref": "AAAAAAGAl12L1ka3Ntc=" + }, + "name": "get_image_data" + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAl441S8CaKhY=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Prop", + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl48EYsUZjkQ=", + "_parent": { + "$ref": "AAAAAAGAl441S8CaKhY=" + }, + "name": "rect", + "type": "pygame.Rect" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGAl4+pJsmHF4I=", + "_parent": { + "$ref": "AAAAAAGAl441S8CaKhY=" + }, + "name": "hit_rect", + "type": "Rect" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAGAl47IncNQv5A=", + "_parent": { + "$ref": "AAAAAAGAl441S8CaKhY=" + }, + "name": "update" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAl4/eCsuMa9A=", + "_parent": { + "$ref": "AAAAAAGAl441S8CaKhY=" + }, + "name": "get_position", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGAl5aFX/m/9TU=", + "_parent": { + "$ref": "AAAAAAGAl4/eCsuMa9A=" + }, + "type": "Tuple", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGArPxSYkB9Khg=", + "_parent": { + "$ref": "AAAAAAGAl441S8CaKhY=" + }, + "name": "__init__", + "visibility": "private", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGArPyb7UEmpVA=", + "_parent": { + "$ref": "AAAAAAGArPxSYkB9Khg=" + }, + "name": "x", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArPyb7UEnlnM=", + "_parent": { + "$ref": "AAAAAAGArPxSYkB9Khg=" + }, + "name": "y", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArPyb7UEovWE=", + "_parent": { + "$ref": "AAAAAAGArPxSYkB9Khg=" + }, + "name": "width", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArPyb7kEp7wo=", + "_parent": { + "$ref": "AAAAAAGArPxSYkB9Khg=" + }, + "name": "height", + "type": "int" + } + ] + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAl57tthZyB50=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Class6" + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGArBYpZe6rwvo=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Class7", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAGArBYrye8uD2Q=", + "_parent": { + "$ref": "AAAAAAGArBYpZe6rwvo=" + }, + "source": { + "$ref": "AAAAAAGAlw1a9IrJsQE=" + }, + "target": { + "$ref": "AAAAAAGAl441S8CaKhY=" + } + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGArBbN0/Tmgq0=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Bullet", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAGA2rRwnxbpX48=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "source": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "target": { + "$ref": "AAAAAAGA2rRtGRaTuHc=" + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArBiWGQg7NCg=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "name": "rect", + "type": "Rect" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArBjXLwkIRBI=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "name": "hit_rect", + "type": "Rect" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArBkIfwn5Kug=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "name": "speed", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArBkvkArqIVs=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "name": "_no", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArBlZ4AvbJ9g=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "name": "rot", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArBl/+wzMK0o=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "name": "move", + "type": "dict" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArBxK+Q9blYo=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "name": "angle", + "type": "float" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAGArJ+EoygkofU=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "name": "update" + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGArPrWkTgeCkg=", + "_parent": { + "$ref": "AAAAAAGArBbN0/Tmgq0=" + }, + "name": "__init__", + "visibility": "private", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGArPtKPjjHQ/c=", + "_parent": { + "$ref": "AAAAAAGArPrWkTgeCkg=" + }, + "name": "player_no", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArPtKPjjIRkQ=", + "_parent": { + "$ref": "AAAAAAGArPrWkTgeCkg=" + }, + "name": "center", + "type": "tuple" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArPtKPjjJGgA=", + "_parent": { + "$ref": "AAAAAAGArPrWkTgeCkg=" + }, + "name": "rot", + "type": "int" + } + ] + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGArJb5pBQr9bw=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Station", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAGArJb8MhSuGlc=", + "_parent": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "source": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "target": { + "$ref": "AAAAAAGAl441S8CaKhY=" + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArJdtyx8pIKU=", + "_parent": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "name": "_no", + "visibility": "protected", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArJfRwCFx2g8=", + "_parent": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "name": "count_frame", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArJgKhyJi2sQ=", + "_parent": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "name": "power", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArPiEKSqP6ng=", + "_parent": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "name": "_id", + "visibility": "protected", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArPjBISuBBXg=", + "_parent": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "name": "count_frame", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArPkGlixyI9Y=", + "_parent": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "name": "capacity", + "type": "int" + }, + { + "_type": "UMLAttribute", + "_id": "AAAAAAGArPlELC5fJfA=", + "_parent": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "name": "cool_down", + "type": "int" + } + ], + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAGArJhdeyTxoTk=", + "_parent": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "name": "get_power", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGArJiOeSWasDM=", + "_parent": { + "$ref": "AAAAAAGArJhdeyTxoTk=" + }, + "type": "int", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGArPmCiTAWIYM=", + "_parent": { + "$ref": "AAAAAAGArJb5pBQr9bw=" + }, + "name": "__init__", + "visibility": "private", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGArPod3zC/3HQ=", + "_parent": { + "$ref": "AAAAAAGArPmCiTAWIYM=" + }, + "name": "_id", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArPod3zDAUwE=", + "_parent": { + "$ref": "AAAAAAGArPmCiTAWIYM=" + }, + "name": "_no", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArPod3zDBBXQ=", + "_parent": { + "$ref": "AAAAAAGArPmCiTAWIYM=" + }, + "name": "x", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArPod4DDCjc0=", + "_parent": { + "$ref": "AAAAAAGArPmCiTAWIYM=" + }, + "name": "y", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArPod4DDDrXw=", + "_parent": { + "$ref": "AAAAAAGArPmCiTAWIYM=" + }, + "name": "width", + "type": "int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGArPod4DDEFA4=", + "_parent": { + "$ref": "AAAAAAGArPmCiTAWIYM=" + }, + "name": "height", + "type": "int" + } + ] + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAt2B/jcsAIYY=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Game", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAGAt2CDMMt0Z9w=", + "_parent": { + "$ref": "AAAAAAGAt2B/jcsAIYY=" + }, + "source": { + "$ref": "AAAAAAGAt2B/jcsAIYY=" + }, + "target": { + "$ref": "AAAAAAGAk4i0rqt7zy4=" + } + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAt2yrkNd9c4Q=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "SoundControler", + "operations": [ + { + "_type": "UMLOperation", + "_id": "AAAAAAGAt21fvOjVin0=", + "_parent": { + "$ref": "AAAAAAGAt2yrkNd9c4Q=" + }, + "name": "player_music", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGA2ren+R8sJls=", + "_parent": { + "$ref": "AAAAAAGAt21fvOjVin0=" + }, + "name": "music_path", + "type": "Str" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGA2ren+R8trQU=", + "_parent": { + "$ref": "AAAAAAGAt21fvOjVin0=" + }, + "name": "volume", + "type": "Float" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGA2ren+R8uSeE=", + "_parent": { + "$ref": "AAAAAAGAt21fvOjVin0=" + }, + "type": "None", + "direction": "return" + } + ] + }, + { + "_type": "UMLOperation", + "_id": "AAAAAAGAt22rxemimug=", + "_parent": { + "$ref": "AAAAAAGAt2yrkNd9c4Q=" + }, + "name": "player_sound", + "parameters": [ + { + "_type": "UMLParameter", + "_id": "AAAAAAGA2rdVuR3THQE=", + "_parent": { + "$ref": "AAAAAAGAt22rxemimug=" + }, + "name": "sound_path", + "type": "Str" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGA2rdVuR3UIQw=", + "_parent": { + "$ref": "AAAAAAGAt22rxemimug=" + }, + "name": "volume", + "type": "Float" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGA2rdVuh3VfZM=", + "_parent": { + "$ref": "AAAAAAGAt22rxemimug=" + }, + "name": "max_time", + "type": "Int" + }, + { + "_type": "UMLParameter", + "_id": "AAAAAAGA2rdVuh3Wa3s=", + "_parent": { + "$ref": "AAAAAAGAt22rxemimug=" + }, + "type": "None", + "direction": "return" + } + ] + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGAux1Tbe7ewXU=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "BattleMode", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAGAux1Wr+9hCM4=", + "_parent": { + "$ref": "AAAAAAGAux1Tbe7ewXU=" + }, + "source": { + "$ref": "AAAAAAGAux1Tbe7ewXU=" + }, + "target": { + "$ref": "AAAAAAGAXjxqgqVefzo=" + } + } + ] + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGA2rRtGRaTuHc=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Bullet" + }, + { + "_type": "UMLClass", + "_id": "AAAAAAGA2r8tmC9NiKo=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "TankSoundControler", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAGA2r8xtC+FTUY=", + "_parent": { + "$ref": "AAAAAAGA2r8tmC9NiKo=" + }, + "source": { + "$ref": "AAAAAAGA2r8tmC9NiKo=" + }, + "target": { + "$ref": "AAAAAAGAt2yrkNd9c4Q=" + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/TankMan/doc/TankMan.png b/TankMan/doc/TankMan.png new file mode 100644 index 0000000..9a35c97 Binary files /dev/null and b/TankMan/doc/TankMan.png differ diff --git a/TankMan/doc/classes.dot b/TankMan/doc/classes.dot new file mode 100644 index 0000000..8ca4ee7 --- /dev/null +++ b/TankMan/doc/classes.dot @@ -0,0 +1,32 @@ +digraph "classes" { +rankdir=BT +charset="utf-8" +"MLGame.games.Game.src.BattleMode.BattleMode" [color="black", fontcolor="black", label="{MLGame.games.Game.src.BattleMode.BattleMode|bullet_stations\lbullets\lis_debug : bool\lis_invincible : bool\lis_through_wall : bool\loil_stations\lplayer_1P\lplayer_2P\lplayers\lstate\lstatus\lwalls\l|check_collisions()\lcheck_events()\lcreate_bullet(shoot_info)\lcreate_game_data_to_player()\lcreate_init_image_data()\lcreate_scene_info()\ldraw_sprite_data()\ldraw_text_data()\lget_result(): list\lreset()\lupdate(command: dict)\l}", shape="record", style="solid"]; +"MLGame.games.Game.src.Bullet.Bullet" [color="black", fontcolor="black", label="{MLGame.games.Game.src.Bullet.Bullet|angle\lhit_rect\lmove : dict\lrect\lrot : int\lspeed : int\l|get_image_data()\lupdate()\l}", shape="record", style="solid"]; +"MLGame.games.Game.src.SingleMode.SingleMode" [color="black", fontcolor="black", label="{MLGame.games.Game.src.SingleMode.SingleMode|all_sprites\lframe_limit\lis_paused : bool\lis_sound : bool\lmap\lmap_path : str\lstate\lstatus\lused_frame : int\lwindow\l|check_collisions()\lcheck_events()\lcreate_game_data_to_player()\lcreate_init_image_data()\lcreate_scene_info()\ldraw_sprite_data()\ldraw_text_data()\lget_result(): list\lplay_music(music_path: str, volume: float)\lplay_sound(music_path: str, volume: float, max_time: int)\lreset()\lupdate(command: dict)\l}", shape="record", style="solid"]; +"MLGame.games.Game.src.I_Commander.I_Commander" [color="black", fontcolor="black", label="{MLGame.games.Game.src.I_Commander.I_Commander|\l|getControlDict(): dict\l}", shape="record", style="solid"]; +"MLGame.games.Game.src.I_Commander.KeyBoardCommander" [color="black", fontcolor="black", label="{MLGame.games.Game.src.I_Commander.KeyBoardCommander|brakeKey\lmoveLeftKey\lmoveRightKey\lno : int\lspeedKey\l|getControlDict()\l}", shape="record", style="solid"]; +"MLGame.games.Game.src.Wall.Wall" [color="black", fontcolor="black", label="{MLGame.games.Game.src.Wall.Wall|img_path_list : list\llives : int\l|collide_with_bullets()\lget_image_data()\lget_image_init_data()\lget_info()\lget_xy_pos()\lupdate(): None\l}", shape="record", style="solid"]; +"MLGame.games.Game.src.PacPlayer.PacPlayer" [color="black", fontcolor="black", label="{MLGame.games.Game.src.PacPlayer.PacPlayer|hit_rect\limage_data : dict\limage_init_data : dict\lis_alive : bool\llives : int\lorigin_center\lorigin_size : tuple\lrect\lresult_info : dict\lscore : int\lused_frame : int\lvel\l|act(commands: str)\lcollide_with_walls()\lget_image_data()\lget_image_init_data()\lget_info()\lget_origin_size()\lget_xy_pos()\lreset()\lupdate(commands: str)\l}", shape="record", style="solid"]; +"MLGame.games.Game.src.Props.Props" [color="black", fontcolor="black", label="{MLGame.games.Game.src.Props.Props|hit_rect\limage_data : dict\limage_init_data : dict, list\limg_path_list : list\lrect\l|get_image_data()\lget_image_init_data()\lget_info()\lget_size()\lget_xy_pos()\lupdate()\l}", shape="record", style="solid"]; +"MLGame.games.Game.src.Station.Station" [color="black", fontcolor="black", label="{MLGame.games.Game.src.Station.Station|capacity : int\lcool_down\lcount_frame : int\lpower : int\lstation_name : str\l|get_image_data()\lget_image_init_data()\lget_info()\lget_power()\lupdate()\l}", shape="record", style="solid"]; +"MLGame.games.Game.src.Game.Game" [color="black", fontcolor="black", label="{MLGame.games.Game.src.Game.Game|attachements : list\lframe_count : int\lgame_mode\lgame_result_state\lget_scene_info\lis_sound : bool\lmap_path\lscene\ltime_limit : int\l|ai_clients()\lgame_to_player_data(): dict\lget_game_result()\lget_keyboard_command()\lget_scene_init_data(): dict\lget_scene_progress_data(): dict\lis_running()\lrank()\lreset()\lset_game_mode()\lupdate(commands: dict)\l}", shape="record", style="solid"]; +"MLGame.games.Game.src.TiledMap.TiledMap" [color="black", fontcolor="black", label="{MLGame.games.Game.src.TiledMap.TiledMap|height : int\ltmx_data\lwidth : int\l|create_img_init_data(img_no_list: list)\l}", shape="record", style="solid"]; +"MLGame.games.Game.src.Player.Player" [color="black", fontcolor="black", label="{MLGame.games.Game.src.Player.Player|angle : float, int\limage_id\limg_path\lis_alive : bool\lis_backward : bool\lis_forward : bool\lis_shoot : bool\llast_shoot_frame : int\llives\lmove : dict\loil : float, int\lpower : int\lrect\lrot : int\lrot_speed : int\lscore : int\lshield : int\lspeed : int\lsurface\lused_frame : int\l|act(commands: str)\lbackward()\lcollide_with_bullets()\lcollide_with_walls()\lcreate_shoot_info()\lforward()\lget_image_data()\lget_image_init_data()\lget_info()\lrotate()\lturn_left()\lturn_right()\lupdate(commands: str)\l}", shape="record", style="solid"]; +"MLGame.games.Game.src.sound_controller.SoundController" [color="black", fontcolor="black", label="{MLGame.games.Game.src.sound_controller.SoundController|is_sound_on : bool\lwarn_sound\l|play_normal_music()\l}", shape="record", style="solid"]; +"abc.ABC" [color="black", fontcolor="black", label="{abc.ABC|\l|}", shape="record", style="solid"]; +"collections.defaultdict" [color="black", fontcolor="black", label="{collections.defaultdict|default_factory : NoneType\l|}", shape="record", style="solid"]; +"pytmx.pytmx.TiledElement" [color="black", fontcolor="black", label="{pytmx.pytmx.TiledElement|properties : dict\l|from_xml_string(xml_string: str): TiledElement\l}", shape="record", style="solid"]; +"pytmx.pytmx.TiledMap" [color="black", fontcolor="black", label="{pytmx.pytmx.TiledMap|background_color : NoneType\lfilename : Optional[str]\lgidmap\lheight : int\lhexsidelength : int\limage_loader\limagemap : dict\limages : list\linvert_y\llayernames : dict\llayers : list\lload_all_tiles\lmaxgid : int\lnextobjectid : int\lobjectgroups\lobjects\lobjects_by_id : dict\lobjects_by_name : dict\loptional_gids\lorientation : str\lrenderorder : str\lstaggeraxis : NoneType\lstaggerindex : NoneType\ltile_properties : dict\ltiledgidmap : dict\ltiledversion : str\ltileheight : int\ltilesets : list\ltilewidth : int\lversion : str\lvisible_layers\lvisible_object_groups\lvisible_tile_layers\lwidth : int\l|add_layer(layer: Union[TiledTileLayer, TiledImageLayer, TiledGroupLayer, TiledObjectGroup]): None\ladd_tileset(tileset: TiledTileset): None\lget_layer_by_name(name: str)\lget_object_by_id(obj_id: int): TiledObject\lget_object_by_name(name): TiledObject\lget_tile_colliders(): Iterable[Tuple[int, List[Dict]]]\lget_tile_gid(x: int, y: int, layer: int): int\lget_tile_image(x: int, y: int, layer: int)\lget_tile_image_by_gid(gid: int)\lget_tile_locations_by_gid(gid: int): Iterable[MapPoint]\lget_tile_properties(x: int, y: int, layer: int): Optional[Dict]\lget_tile_properties_by_gid(gid: int): Optional[Dict]\lget_tile_properties_by_layer(layer: int)\lget_tileset_from_gid(gid: int): TiledTileset\lmap_gid(tiled_gid: int): Optional[List[int]]\lmap_gid2(tiled_gid: int): List[Tuple[int, Optional[int]]]\lparse_xml(node: ElementTree.Element)\lregister_gid(tiled_gid: int, flags: Optional[TileFlags]): int\lreload_images(): None\lset_tile_properties(gid: int, properties: dict): None\l}", shape="record", style="solid"]; +"MLGame.games.Game.src.BattleMode.BattleMode" -> "MLGame.games.Game.src.SingleMode.SingleMode" [arrowhead="empty", arrowtail="none"]; +"MLGame.games.Game.src.I_Commander.I_Commander" -> "abc.ABC" [arrowhead="empty", arrowtail="none"]; +"MLGame.games.Game.src.I_Commander.KeyBoardCommander" -> "MLGame.games.Game.src.I_Commander.I_Commander" [arrowhead="empty", arrowtail="none"]; +"MLGame.games.Game.src.Wall.Wall" -> "MLGame.games.Game.src.Props.Props" [arrowhead="empty", arrowtail="none"]; +"MLGame.games.Game.src.Player.Player" -> "MLGame.games.Game.src.PacPlayer.PacPlayer" [arrowhead="empty", arrowtail="none"]; +"pytmx.pytmx.TiledMap" -> "pytmx.pytmx.TiledElement" [arrowhead="empty", arrowtail="none"]; +"MLGame.games.Game.src.BattleMode.BattleMode" -> "MLGame.games.Game.src.Game.Game" [arrowhead="diamond", arrowtail="none", fontcolor="green", label="game_mode", style="solid"]; +"MLGame.games.Game.src.BattleMode.BattleMode" -> "MLGame.games.Game.src.Game.Game" [arrowhead="diamond", arrowtail="none", fontcolor="green", label="game_mode", style="solid"]; +"MLGame.games.Game.src.TiledMap.TiledMap" -> "MLGame.games.Game.src.SingleMode.SingleMode" [arrowhead="diamond", arrowtail="none", fontcolor="green", label="map", style="solid"]; +"collections.defaultdict" -> "pytmx.pytmx.TiledMap" [arrowhead="diamond", arrowtail="none", fontcolor="green", label="gidmap", style="solid"]; +"pytmx.pytmx.TiledMap" -> "MLGame.games.Game.src.TiledMap.TiledMap" [arrowhead="diamond", arrowtail="none", fontcolor="green", label="tmx_data", style="solid"]; +} diff --git a/TankMan/doc/packages.dot b/TankMan/doc/packages.dot new file mode 100644 index 0000000..baf45af --- /dev/null +++ b/TankMan/doc/packages.dot @@ -0,0 +1,36 @@ +digraph "packages" { +rankdir=BT +charset="utf-8" +"MLGame.games.Game.src" [color="black", label="MLGame.games.Game.src", shape="box", style="solid"]; +"MLGame.games.Game.src.BattleMode" [color="black", label="MLGame.games.Game.src.BattleMode", shape="box", style="solid"]; +"MLGame.games.Game.src.Bullet" [color="black", label="MLGame.games.Game.src.Bullet", shape="box", style="solid"]; +"MLGame.games.Game.src.SingleMode" [color="black", label="MLGame.games.Game.src.SingleMode", shape="box", style="solid"]; +"MLGame.games.Game.src.I_Commander" [color="black", label="MLGame.games.Game.src.I_Commander", shape="box", style="solid"]; +"MLGame.games.Game.src.Wall" [color="black", label="MLGame.games.Game.src.Wall", shape="box", style="solid"]; +"MLGame.games.Game.src.PacPlayer" [color="black", label="MLGame.games.Game.src.PacPlayer", shape="box", style="solid"]; +"MLGame.games.Game.src.Props" [color="black", label="MLGame.games.Game.src.Props", shape="box", style="solid"]; +"MLGame.games.Game.src.Station" [color="black", label="MLGame.games.Game.src.Station", shape="box", style="solid"]; +"MLGame.games.Game.src.Game" [color="black", label="MLGame.games.Game.src.Game", shape="box", style="solid"]; +"MLGame.games.Game.src.TiledMap" [color="black", label="MLGame.games.Game.src.TiledMap", shape="box", style="solid"]; +"MLGame.games.Game.src.Player" [color="black", label="MLGame.games.Game.src.Player", shape="box", style="solid"]; +"MLGame.games.Game.src.collide_hit_rect" [color="black", label="MLGame.games.Game.src.collide_hit_rect", shape="box", style="solid"]; +"MLGame.games.Game.src.env" [color="black", label="MLGame.games.Game.src.env", shape="box", style="solid"]; +"MLGame.games.Game.src.sound_controller" [color="black", label="MLGame.games.Game.src.sound_controller", shape="box", style="solid"]; +"MLGame.games.Game.src.test_case" [color="black", label="MLGame.games.Game.src.test_case", shape="box", style="solid"]; +"MLGame.games.Game.src.BattleMode" -> "MLGame.games.Game.src.Bullet" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.BattleMode" -> "MLGame.games.Game.src.SingleMode" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.BattleMode" -> "MLGame.games.Game.src.collide_hit_rect" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.Bullet" -> "MLGame.games.Game.src.env" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.SingleMode" -> "MLGame.games.Game.src.TiledMap" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.SingleMode" -> "MLGame.games.Game.src.env" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.Wall" -> "MLGame.games.Game.src.Props" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.Wall" -> "MLGame.games.Game.src.env" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.Station" -> "MLGame.games.Game.src.env" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.Game" -> "MLGame.games.Game.src.BattleMode" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.Game" -> "MLGame.games.Game.src.sound_controller" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.Player" -> "MLGame.games.Game.src.PacPlayer" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.Player" -> "MLGame.games.Game.src.env" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.collide_hit_rect" -> "MLGame.games.Game.src.Station" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.collide_hit_rect" -> "MLGame.games.Game.src.env" [arrowhead="open", arrowtail="none"]; +"MLGame.games.Game.src.sound_controller" -> "MLGame.games.Game.src.env" [arrowhead="open", arrowtail="none"]; +} diff --git a/TankMan/game_config.json b/TankMan/game_config.json new file mode 100644 index 0000000..00b06dc --- /dev/null +++ b/TankMan/game_config.json @@ -0,0 +1,77 @@ +{ + "game_name": "TankMan", + "version": "funai", + "url": "https://github.com/PAIA-Playful-AI-Arena/TankMan.git", + "description": "坦克人(Tank Man),一款經典的雙人對戰遊戲,時間內率先擊殺對手獲勝,否則以分數高者獲勝,除了擊中對手外,破壞遊戲物件,以獲得更高積分。注意: 場上資源恢復皆須時間,先到者得,你需要這些補充品以提供前進和射擊的燃油和子彈。", + "logo": [ + "./asset/image/TankMan.svg", + "https://raw.githubusercontent.com/PAIA-Playful-AI-Arena/TankMan/main/asset/image/TankMan.svg" + ], + "user_num": { + "min": 2, + "max": 6 + }, + "game_params": [ + { + "name": "green_team_num", + "verbose": "A隊人數為:", + "type": "int", + "max": 5, + "min": 1, + "help": "set the number of green_team users.", + "default": 1 + }, + { + "name": "blue_team_num", + "verbose": "B隊人數為:", + "type": "int", + "max": 5, + "min": 1, + "help": "set the number of blue_team users.", + "default": 1 + }, + { + "name": "is_manual", + "verbose": "使否手動遊玩", + "type": "str", + "choices": [ + { + "verbose": "是", + "value": "1" + }, + { + "verbose": "否", + "value": "" + } + ], + "help": "'1' can turn on the player rotate cool down .", + "default": 0 + }, + { + "name": "frame_limit", + "verbose": "遊戲總幀數(Frame)", + "type": "int", + "max": 3000, + "min": 30, + "default": 300, + "help": "set the frame number of game frame limit." + }, + { + "name": "sound", + "verbose": "遊戲音效", + "type": "str", + "choices": [ + { + "verbose": "開", + "value": "on" + }, + { + "verbose": "關", + "value": "off" + } + ], + "help": "'on' can turn on the sound.", + "default": "off" + } + ] +} diff --git a/TankMan/geraterate_game.py b/TankMan/geraterate_game.py new file mode 100644 index 0000000..3738b83 --- /dev/null +++ b/TankMan/geraterate_game.py @@ -0,0 +1,76 @@ +import importlib +from contest import Contest +def import_player(group_number, player_number): + module_name = f"ml.Group_{group_number}.ml_play_{player_number}" + module = importlib.import_module(module_name) + return getattr(module, f"MLPlay") + +num_groups = 3 +players_per_group = 3 + +players = {} + + +Group_mapping = { + "A" : "1", + "B" : "1", + "C" : "1", + "D" : "1", + "E" : "1", + "F" : "1", + "G" : "1", + "H" : "1", + "I" : "1", + } + + +for group in Group_mapping: + for player in range(1, players_per_group + 1): + player_key = f"player{group}_{player}" + players[player_key] = import_player(Group_mapping[group], player) + +record = {} +for group in Group_mapping: + record[f"Group_{group}"] = 0 + +if __name__ == '__main__': + sound = "off" + total_game = 5 + frame = 2500 + is_manual = False + + + Games = [] + for group_i in Group_mapping: + for group_j in Group_mapping: + if group_i != group_j: + game = { "players" : [ + players[f"player{group_i}_{k+1}"] for k in range(players_per_group)] + + [players[f"player{group_j}_{k+1}"] for k in range(players_per_group)], + "home": group_i, + "away": group_j + } + Games.append(game) + + + for game in Games: + + selected_players = [game["players"][0]('1P', {'sound': sound}), + game["players"][1]('2P', {'sound': sound}), + game["players"][2]('3P', {'sound': sound}), + game["players"][3]('4P', {'sound': sound}), + game["players"][4]('5P', {'sound': sound}), + game["players"][5]('6P', {'sound': sound})] + + contest_instance = Contest(selected_players, total_game, frame, sound, is_manual) + result = contest_instance.run() + + if result["green_team_win"] > result["blue_team_win"]: + record[f"Group_{game['home']}"] += 1 + else: + record[f"Group_{game['away']}"] += 1 + print("home:", "Group_"+str(game["home"]), result["green_team_win"], "VS", result["blue_team_win"] ,"away", "Group_"+str(game["away"])) + print(record) + input("Press Enter to continue...") + + diff --git a/TankMan/ml/Group_1/ml_play_1.py b/TankMan/ml/Group_1/ml_play_1.py new file mode 100644 index 0000000..a939d6e --- /dev/null +++ b/TankMan/ml/Group_1/ml_play_1.py @@ -0,0 +1,70 @@ +""" +The template of the main script of the machine learning process +""" +import random +import pygame + +from src.env import IS_DEBUG + + +class MLPlay: + def __init__(self, ai_name, *args, **kwargs): + """ + Constructor + + @param side A string "1P" or "2P" indicates that the `MLPlay` is used by + which side. + """ + self.side = ai_name + print(f"Initial Game {ai_name} ml script") + self.time = 0 + + def update(self, scene_info: dict, keyboard=[], *args, **kwargs): + """ + Generate the command according to the received scene information + """ + # print(keyboard) + + if scene_info["status"] != "GAME_ALIVE": + # print(scene_info) + return "RESET" + move_act = random.randrange(5) + aim_act = random.randrange(3) + shoot_cd = random.randrange(15, 31) + + is_shoot = 0 + if scene_info["used_frame"] % shoot_cd == 0: + is_shoot = random.randrange(2) + + command = [] + if move_act == 1: + command.append("TURN_RIGHT") + elif move_act == 2: + command.append("TURN_LEFT") + elif move_act == 3: + command.append("FORWARD") + elif move_act == 4: + command.append("BACKWARD") + + if aim_act == 1: + command.append("AIM_LEFT") + elif aim_act == 2: + command.append("AIM_RIGHT") + + if is_shoot and not IS_DEBUG: + command.append("SHOOT") + + if self.side == "1P": + if pygame.K_b in keyboard: + command.append("DEBUG") + + if not command: + command.append("NONE") + + return command + + def reset(self): + """ + Reset the status + """ + print(f"reset Game {self.side}") \ No newline at end of file diff --git a/TankMan/ml/Group_1/ml_play_2.py b/TankMan/ml/Group_1/ml_play_2.py new file mode 100644 index 0000000..a939d6e --- /dev/null +++ b/TankMan/ml/Group_1/ml_play_2.py @@ -0,0 +1,70 @@ +""" +The template of the main script of the machine learning process +""" +import random +import pygame + +from src.env import IS_DEBUG + + +class MLPlay: + def __init__(self, ai_name, *args, **kwargs): + """ + Constructor + + @param side A string "1P" or "2P" indicates that the `MLPlay` is used by + which side. + """ + self.side = ai_name + print(f"Initial Game {ai_name} ml script") + self.time = 0 + + def update(self, scene_info: dict, keyboard=[], *args, **kwargs): + """ + Generate the command according to the received scene information + """ + # print(keyboard) + + if scene_info["status"] != "GAME_ALIVE": + # print(scene_info) + return "RESET" + move_act = random.randrange(5) + aim_act = random.randrange(3) + shoot_cd = random.randrange(15, 31) + + is_shoot = 0 + if scene_info["used_frame"] % shoot_cd == 0: + is_shoot = random.randrange(2) + + command = [] + if move_act == 1: + command.append("TURN_RIGHT") + elif move_act == 2: + command.append("TURN_LEFT") + elif move_act == 3: + command.append("FORWARD") + elif move_act == 4: + command.append("BACKWARD") + + if aim_act == 1: + command.append("AIM_LEFT") + elif aim_act == 2: + command.append("AIM_RIGHT") + + if is_shoot and not IS_DEBUG: + command.append("SHOOT") + + if self.side == "1P": + if pygame.K_b in keyboard: + command.append("DEBUG") + + if not command: + command.append("NONE") + + return command + + def reset(self): + """ + Reset the status + """ + print(f"reset Game {self.side}") \ No newline at end of file diff --git a/TankMan/ml/Group_1/ml_play_3.py b/TankMan/ml/Group_1/ml_play_3.py new file mode 100644 index 0000000..a939d6e --- /dev/null +++ b/TankMan/ml/Group_1/ml_play_3.py @@ -0,0 +1,70 @@ +""" +The template of the main script of the machine learning process +""" +import random +import pygame + +from src.env import IS_DEBUG + + +class MLPlay: + def __init__(self, ai_name, *args, **kwargs): + """ + Constructor + + @param side A string "1P" or "2P" indicates that the `MLPlay` is used by + which side. + """ + self.side = ai_name + print(f"Initial Game {ai_name} ml script") + self.time = 0 + + def update(self, scene_info: dict, keyboard=[], *args, **kwargs): + """ + Generate the command according to the received scene information + """ + # print(keyboard) + + if scene_info["status"] != "GAME_ALIVE": + # print(scene_info) + return "RESET" + move_act = random.randrange(5) + aim_act = random.randrange(3) + shoot_cd = random.randrange(15, 31) + + is_shoot = 0 + if scene_info["used_frame"] % shoot_cd == 0: + is_shoot = random.randrange(2) + + command = [] + if move_act == 1: + command.append("TURN_RIGHT") + elif move_act == 2: + command.append("TURN_LEFT") + elif move_act == 3: + command.append("FORWARD") + elif move_act == 4: + command.append("BACKWARD") + + if aim_act == 1: + command.append("AIM_LEFT") + elif aim_act == 2: + command.append("AIM_RIGHT") + + if is_shoot and not IS_DEBUG: + command.append("SHOOT") + + if self.side == "1P": + if pygame.K_b in keyboard: + command.append("DEBUG") + + if not command: + command.append("NONE") + + return command + + def reset(self): + """ + Reset the status + """ + print(f"reset Game {self.side}") \ No newline at end of file diff --git a/TankMan/ml/QT.py b/TankMan/ml/QT.py new file mode 100644 index 0000000..c553fd0 --- /dev/null +++ b/TankMan/ml/QT.py @@ -0,0 +1,39 @@ +import numpy as np +import pandas as pd + +class QLearningTable: + def __init__(self,actions,learning_rate=0.05,reward_decay=0.9,e_greedy=0.1): + + self.actions=actions + self.lr=learning_rate + self.gamma=reward_decay + self.epsilon=e_greedy + + self.q_table=pd.DataFrame(columns=self.actions,dtype=np.float64) + + def choose_action(self,observation): + self.check_state_exist(observation) + + #action selection + if np.random.uniform()>self.epsilon: + state_action =self.q_table.loc[observation,:] + action =np.random.choice(state_action[state_action==np.max(state_action)].index) + else: + action = np.random.choice(self.actions) + + return action + + def learn(self,s,a,r,s_): + self.check_state_exist(s) + self.check_state_exist(s_) + q_predict=self.q_table.loc[s,a] + if s_!='Game_over' or s_!='Game_pass': + q_target =r+self.gamma*self.q_table.loc[s_,:].max() + else: + q_target=r + self.q_table.loc[s,a]+=self.lr*(q_target-q_predict) + + def check_state_exist(self,state): + if state not in list(self.q_table.index): + new_row = pd.Series([0]*len(self.actions), index=self.q_table.columns, name=state) + self.q_table = pd.concat([self.q_table, pd.DataFrame(new_row).T]) \ No newline at end of file diff --git a/TankMan/ml/__init__.py b/TankMan/ml/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/TankMan/ml/ml_play.py b/TankMan/ml/ml_play.py new file mode 100644 index 0000000..a939d6e --- /dev/null +++ b/TankMan/ml/ml_play.py @@ -0,0 +1,70 @@ +""" +The template of the main script of the machine learning process +""" +import random +import pygame + +from src.env import IS_DEBUG + + +class MLPlay: + def __init__(self, ai_name, *args, **kwargs): + """ + Constructor + + @param side A string "1P" or "2P" indicates that the `MLPlay` is used by + which side. + """ + self.side = ai_name + print(f"Initial Game {ai_name} ml script") + self.time = 0 + + def update(self, scene_info: dict, keyboard=[], *args, **kwargs): + """ + Generate the command according to the received scene information + """ + # print(keyboard) + + if scene_info["status"] != "GAME_ALIVE": + # print(scene_info) + return "RESET" + move_act = random.randrange(5) + aim_act = random.randrange(3) + shoot_cd = random.randrange(15, 31) + + is_shoot = 0 + if scene_info["used_frame"] % shoot_cd == 0: + is_shoot = random.randrange(2) + + command = [] + if move_act == 1: + command.append("TURN_RIGHT") + elif move_act == 2: + command.append("TURN_LEFT") + elif move_act == 3: + command.append("FORWARD") + elif move_act == 4: + command.append("BACKWARD") + + if aim_act == 1: + command.append("AIM_LEFT") + elif aim_act == 2: + command.append("AIM_RIGHT") + + if is_shoot and not IS_DEBUG: + command.append("SHOOT") + + if self.side == "1P": + if pygame.K_b in keyboard: + command.append("DEBUG") + + if not command: + command.append("NONE") + + return command + + def reset(self): + """ + Reset the status + """ + print(f"reset Game {self.side}") \ No newline at end of file diff --git a/TankMan/ml/ml_play_manual.py b/TankMan/ml/ml_play_manual.py new file mode 100644 index 0000000..842391e --- /dev/null +++ b/TankMan/ml/ml_play_manual.py @@ -0,0 +1,79 @@ +""" +The template of the main script of the machine learning process +""" + +import pygame + + +class MLPlay: + def __init__(self, ai_name, *args, **kwargs): + """ + Constructor + + @param ai_name A string "1P" or "2P" indicates that the `MLPlay` is used by + which side. + """ + self.side = ai_name + print(f"Initial Game {ai_name} ml script") + self.time = 0 + + def update(self, scene_info: dict, keyboard=[], *args, **kwargs): + """ + Generate the command according to the received scene information + """ + if scene_info["status"] != "GAME_ALIVE": + # print(scene_info) + return "RESET" + command = [] + if self.side == "1P": + print(scene_info["oil"]) + if pygame.K_RIGHT in keyboard: + command.append("TURN_RIGHT") + elif pygame.K_LEFT in keyboard: + command.append("TURN_LEFT") + elif pygame.K_UP in keyboard: + command.append("FORWARD") + elif pygame.K_DOWN in keyboard: + command.append("BACKWARD") + + if pygame.K_z in keyboard: + command.append("AIM_LEFT") + elif pygame.K_x in keyboard: + command.append("AIM_RIGHT") + + if pygame.K_m in keyboard: + command.append("SHOOT") + # debug + if pygame.K_b in keyboard: + command.append("DEBUG") + # paused + if pygame.K_t in keyboard: + command.append("PAUSED") + elif self.side == "2P": + if pygame.K_d in keyboard: + command.append("TURN_RIGHT") + elif pygame.K_a in keyboard: + command.append("TURN_LEFT") + elif pygame.K_w in keyboard: + command.append("FORWARD") + elif pygame.K_s in keyboard: + command.append("BACKWARD") + + if pygame.K_q in keyboard: + command.append("AIM_LEFT") + elif pygame.K_e in keyboard: + command.append("AIM_RIGHT") + + if pygame.K_f in keyboard: + command.append("SHOOT") + + if not command: + command.append("NONE") + + return command + + def reset(self): + """ + Reset the status + """ + print(f"reset Game {self.side}") diff --git a/TankMan/requirements.txt b/TankMan/requirements.txt new file mode 100644 index 0000000..a4782f0 --- /dev/null +++ b/TankMan/requirements.txt @@ -0,0 +1,2 @@ +pytmx == 3.31 +mlgame \ No newline at end of file diff --git a/TankMan/scripts/profile.pstats b/TankMan/scripts/profile.pstats new file mode 100644 index 0000000..e3f25a0 Binary files /dev/null and b/TankMan/scripts/profile.pstats differ diff --git a/TankMan/scripts/profile.pstats.png b/TankMan/scripts/profile.pstats.png new file mode 100644 index 0000000..299bd4b Binary files /dev/null and b/TankMan/scripts/profile.pstats.png differ diff --git a/TankMan/scripts/profile.sh b/TankMan/scripts/profile.sh new file mode 100644 index 0000000..9b6bc5a --- /dev/null +++ b/TankMan/scripts/profile.sh @@ -0,0 +1,19 @@ +export FILE=profile.pstats + +python -m cProfile -s cumtime -o $FILE \ +-m mlgame \ +-i ../ml/ml_play_template_1P.py \ +-i ../ml/ml_play_template_1P.py \ +-i ../ml/ml_play_template_1P.py \ +-i ../ml/ml_play_template_1P.py \ +-i ../ml/ml_play_template_1P.py \ +-i ../ml/ml_play_template_2P.py \ +-f 120 -1 \ +../ \ +--frame_limit=30 --sound="off" + +python -m gprof2dot -f pstats $FILE | dot -T png -o ${FILE}.png + +# python -m pstats profile.pstats +# sort cumtime +# stats diff --git a/TankMan/scripts/test_local_server.sh b/TankMan/scripts/test_local_server.sh new file mode 100644 index 0000000..afd9f6b --- /dev/null +++ b/TankMan/scripts/test_local_server.sh @@ -0,0 +1,7 @@ +python -m mlgame \ +--ws="wss://demo.piesocket.com/v3/jesse?api_key=VCXCEuvhGcBDP7XhiJJUDvR1e1D3eiVjgZ9VRiaV" \ +-f 30 --nd -1 \ +-i ../ml/ml_play_template_1P.py \ +-i ../ml/ml_play_template_2P.py \ +../ \ +--frame_limit 300 diff --git a/TankMan/src/Bullet.py b/TankMan/src/Bullet.py new file mode 100644 index 0000000..ff051dd --- /dev/null +++ b/TankMan/src/Bullet.py @@ -0,0 +1,80 @@ +from os import path + +import pygame +from mlgame.view.view_model import create_asset_init_data, create_image_view_data + +from .env import WINDOW_HEIGHT, WINDOW_WIDTH, IMAGE_DIR + +Vec = pygame.math.Vector2 + + +class Bullet(pygame.sprite.Sprite): + def __init__(self, construction, **kwargs): + super().__init__() + self.id = construction["_id"] + self.no = construction["_no"] + self.rect = pygame.Rect((0, 0), construction["_init_size"]) + self.rect.center = construction["_init_pos"] + self.rot = kwargs["rot"] + self.play_rect_area = kwargs["play_rect_area"] + self.speed = kwargs["bullet_speed"] + self.map_width = WINDOW_WIDTH + self.map_height = WINDOW_HEIGHT + self.angle = 3.14 / 180 * (self.rot + 90) + # Refactor + if 7 > self.angle > 6: + self.angle = 0 + self.sqrt2 = 1.414 + self.move = {"left_up": Vec(-self.speed/self.sqrt2, -self.speed/self.sqrt2), + "right_up": Vec(self.speed/self.sqrt2, -self.speed/self.sqrt2), + "left_down": Vec(-self.speed/self.sqrt2, self.speed/self.sqrt2), + "right_down": Vec(self.speed/self.sqrt2, self.speed)/self.sqrt2, + "left": Vec(-self.speed, 0), "right": Vec(self.speed, 0), "up": Vec(0, -self.speed), + "down": Vec(0, self.speed)} + + self.max_travel_distance = (kwargs["bullet_travel_distance"] // self.speed + 1) * self.speed + + self.travel_distance = 0 + + def update(self): + self.travel_distance += self.speed + + if self.play_rect_area.top < self.rect.centery < self.play_rect_area.bottom \ + and self.play_rect_area.left < self.rect.centerx < self.play_rect_area.right: + is_out = False + else: + is_out = True + + if is_out or self.travel_distance >= self.max_travel_distance: + self.kill() + + if self.rot == 0 or self.rot == 360: + self.rect.center += self.move["left"] + elif self.rot == 315 or self.rot == -45: + self.rect.center += self.move["left_up"] + elif self.rot == 270 or self.rot == -90: + self.rect.center += self.move["up"] + elif self.rot == 225 or self.rot == -135: + self.rect.center += self.move["right_up"] + elif self.rot == 180 or self.rot == -180: + self.rect.center += self.move["right"] + elif self.rot == 135 or self.rot == -225: + self.rect.center += self.move["right_down"] + elif self.rot == 90 or self.rot == -270: + self.rect.center += self.move["down"] + elif self.rot == 45 or self.rot == -315: + self.rect.center += self.move["left_down"] + + def get_obj_progress_data(self): + img_id = "team_a_bullet" if self.id == 1 else "team_b_bullet" + return create_image_view_data(img_id, self.rect.x, self.rect.y, self.rect.width, self.rect.height, + self.angle) + + def get_data_from_obj_to_game(self) -> dict: + info = {"id": f"{self.no}P_bullet", + "x": self.rect.x, + "y": self.rect.y, + "speed": self.speed, + "rot": self.rot + } + return info diff --git a/TankMan/src/Game.py b/TankMan/src/Game.py new file mode 100644 index 0000000..64282a8 --- /dev/null +++ b/TankMan/src/Game.py @@ -0,0 +1,116 @@ +from os import path + +import pygame +from mlgame.game.paia_game import PaiaGame, GameStatus +from mlgame.view.view_model import Scene + +from .TeamBattleMode import TeamBattleMode +from .game_module.fuctions import get_sprites_progress_data + +MAP_WIDTH = 1000 +MAP_HEIGHT = 600 +GAME_DIR = path.dirname(__file__) +MAP_DIR = path.join(GAME_DIR, "..", "asset", "maps") +SOUND_DIR = path.join(GAME_DIR, "..", "asset", "sound") +IMAGE_DIR = path.join(GAME_DIR, "..", "asset", "image") + + +class Game(PaiaGame): + def __init__(self, user_num: int, green_team_num: int, blue_team_num: int, is_manual: str, frame_limit: int, sound: str): + super().__init__(user_num) + # init game + self.green_team_num = green_team_num + self.blue_team_num = blue_team_num + self.is_paused = False + self.is_debug = False + self.is_sound = False + self.is_manual = False + if sound == "on": + self.is_sound = True + if is_manual: + self.is_manual = True + self.attachements = [] + self.frame_limit = frame_limit + self.game_mode = self.set_game_mode() + self.scene = Scene(width=self.game_mode.scene_width, height=self.game_mode.scene_height, color="#ffffff", + bias_y=50) + + def get_data_from_game_to_player(self) -> dict: + to_players_data = self.game_mode.get_ai_data_to_player() + return to_players_data + + def update(self, commands: dict): + self.handle_event(commands) + self.game_mode.debugging(self.is_debug) + if not self.is_paused: + self.frame_count += 1 + self.game_mode.update(commands) + if not self.is_running(): + return "RESET" + + def reset(self): + self.frame_count = 0 + self.game_mode.reset() + # self.rank() + + def get_scene_init_data(self) -> dict: + """ + Get the scene and object information for drawing on the web + """ + game_info = {'scene': self.scene.__dict__, + 'assets': self.game_mode.get_init_image_data()} + + return game_info + + def get_scene_progress_data(self) -> dict: + """ + Get the position of src objects for drawing on the web + """ + scene_progress = {'background': [], + 'object_list': [*self.game_mode.background, *self.get_obj_progress_data()], + 'toggle_with_bias': [*self.game_mode.get_toggle_with_bias_data()], + 'toggle': self.game_mode.get_toggle_progress_data(), + 'foreground': [], + 'user_info': [], + 'game_sys_info': {}} + + return scene_progress + + def get_obj_progress_data(self): + obj_list = [] + for sprites in self.game_mode.obj_list: + obj_list.extend(get_sprites_progress_data(sprites)) + obj_list.extend(self.game_mode.obj_rect_list) + return obj_list + + def get_game_result(self): + """ + Get the src result for the web + """ + self.rank() + return {"frame_used": self.frame_count, + "state": self.game_result_state, + "attachment": self.attachements + } + + def is_running(self): + return self.game_mode.status == GameStatus.GAME_ALIVE + + def rank(self): + self.game_result_state = self.game_mode.state + self.attachements = self.game_mode.get_player_result() + return self.attachements + + def handle_event(self, commands): + if ["DEBUG"] in commands.values(): + self.is_debug = not self.is_debug + if ["PAUSED"] in commands.values(): + self.is_paused = not self.is_paused + + def set_game_mode(self): + sound_path = "" + if self.is_sound: + sound_path = SOUND_DIR + play_rect_area = pygame.Rect(0, 0, MAP_WIDTH, MAP_HEIGHT) + game_mode = TeamBattleMode(self.green_team_num, self.blue_team_num, self.is_manual, self.frame_limit, sound_path, play_rect_area) + return game_mode diff --git a/TankMan/src/GenerateMap.py b/TankMan/src/GenerateMap.py new file mode 100644 index 0000000..8630581 --- /dev/null +++ b/TankMan/src/GenerateMap.py @@ -0,0 +1,153 @@ +from os import path +import random +import math + + +PLAYER_NUM = 1 +OIL_NUM = 2 +BULLET_NUM = 2 +MAP_DIR = path.join(path.dirname(__file__), "..", "asset", 'maps') +MAP_VERSION = "1.9" +TILED_VERSION = "1.9.2" + + +class MapGenerator: + + def __init__(self, green_team_num : int, blue_team_num : int, width : int, height : int) -> None: + + self.green_team_num = green_team_num + self.blue_team_num = blue_team_num + + # height should be a factor of 600 + # default is 20, 12 + + self.width = width + self.height = height + + self.height_per_tile = math.floor(600/self.height) + self.width_per_tile = self.height_per_tile + + self.screen_width = self.width * self.height_per_tile + self.screen_height = 700 + + def getTileSize(self) -> int: + return self.height_per_tile + + def getScreeenSize(self) -> tuple: + return self.screen_width, self.screen_height + + def pos2index(self, x : int, y : int) -> int: + return y * (self.width * 2 + 1) + x * 2 + + def mirrored_pos(self, x : int, y : int) -> tuple: + return self.width - x - 1, self.height - y - 1 + + def random_pos(self, map_arr) -> tuple: + random_x, random_y = random.randint(1, self.width-2), random.randint(1, self.height-2) + mir_x, mir_y = self.mirrored_pos(random_x, random_y) + while map_arr[random_y][random_x] != 0 or map_arr[mir_y][mir_x] != 0: + random_x, random_y = random.randint(1, self.width-2), random.randint(1, self.height-2) + mir_x, mir_y = self.mirrored_pos(random_x, random_y) + + return random_x, random_y + + def generate_map_str(self) -> str: + + # generate default map[y][x] + map_arr = [[0 for _ in range(self.width)] for _ in range(self.height)] + + for x in range(self.width): + map_arr[0][x] = 3 + map_arr[self.height-1][x] = 3 + + for y in range(self.height): + map_arr[y][0] = 3 + map_arr[y][self.width-1] = 3 + + if self.width % 2 == 1: + for y in range(1, self.height-1): + map_arr[y][self.width//2] = 3 + else: + for y in range(1, self.height): + if y < math.ceil(self.height/2): + map_arr[y][self.width//2-1] = 3 + else: + map_arr[y][self.width//2] = 3 + + # add player + for _ in range(min(self.green_team_num, self.blue_team_num)): + rand_x, rand_y = self.random_pos(map_arr) + while rand_x < self.width // 2: + rand_x, rand_y = self.random_pos(map_arr) + mir_x, mir_y = self.mirrored_pos(rand_x, rand_y) + + map_arr[rand_y][rand_x] = 1 + map_arr[mir_y][mir_x] = 2 + + # add remaining green team + for _ in range(self.green_team_num - self.blue_team_num): + rand_x, rand_y = self.random_pos(map_arr) + while rand_x < self.width // 2: + rand_x, rand_y = self.random_pos(map_arr) + + map_arr[rand_y][rand_x] = 1 + + # add remaining blue team + for _ in range(self.blue_team_num - self.green_team_num): + rand_x, rand_y = self.random_pos(map_arr) + while rand_x >= self.width // 2: + rand_x, rand_y = self.random_pos(map_arr) + + map_arr[rand_y][rand_x] = 2 + + # add bullet station + for _ in range(BULLET_NUM): + rand_x, rand_y = self.random_pos(map_arr) + mir_x, mir_y = self.mirrored_pos(rand_x, rand_y) + map_arr[rand_y][rand_x] = 4 + map_arr[mir_y][mir_x] = 4 + + # add oil station + for _ in range(OIL_NUM): + rand_x, rand_y = self.random_pos(map_arr) + mir_x, mir_y = self.mirrored_pos(rand_x, rand_y) + map_arr[rand_y][rand_x] = 5 + map_arr[mir_y][mir_x] = 5 + + map_str = "" + + for row in map_arr: + for id in row: + map_str += str(id) + "," + map_str += "\n" + map_str = map_str[:-2] + + return map_str + + def generate_map(self): + map_name = f"map_{self.green_team_num}_v_{self.blue_team_num}.tmx" + map_path = path.join(MAP_DIR, map_name) + print(f'generate map at : {map_path}', flush=True) + + with open(map_path, "w") as file: + # file.write("test") + file.write(f"""\ + + + + + + + +{self.generate_map_str()} + + + + """) + + +if __name__ == "__main__": + map_generator = MapGenerator(1, 1) + map_generator.generate_map() + + diff --git a/TankMan/src/Gun.py b/TankMan/src/Gun.py new file mode 100644 index 0000000..97f87b7 --- /dev/null +++ b/TankMan/src/Gun.py @@ -0,0 +1,106 @@ +from os import path + +import pygame +from mlgame.view.view_model import (create_asset_init_data, + create_image_view_data) + +from .env import IMAGE_DIR + + +class Gun(pygame.sprite.Sprite): + def __init__(self, id, pos, size, **kwargs): + super().__init__() + self.id = id + self.rect = pygame.Rect(pos, size) + self.origin_size = (self.rect.width, self.rect.height) + self.draw_pos = self.rect.topleft + self.surface = pygame.Surface(self.origin_size) + self.rot = 0 + self.rot_speed = 45 + + self.used_frame = 0 + self.last_turn_frame = self.used_frame + self.act_cd = kwargs["act_cd"] + + self.is_alive = True + self.is_turn_left = False + self.is_turn_right = False + + if self.id == 1: + self.pivot_offset = pygame.Vector2(-8, 0) + else: + self.pivot_offset = pygame.Vector2(8, 0) + + def update(self, gun_pos): + self.used_frame += 1 + self.rotate() + + if not self.act_cd: + self.is_turn_right = False + self.is_turn_left = False + elif self.used_frame - self.last_turn_frame > self.act_cd: + self.is_turn_right = False + self.is_turn_left = False + + self.rect.center = gun_pos + self.pivot_offset.rotate(-self.rot) + self.draw_pos = self.rect.topleft + + def rotate(self): + self.rot = self.rot % 360 + self.angle = 3.14 / 180 * self.rot + new_sur = pygame.transform.rotate(self.surface, self.rot) + origin_center = self.rect.center + self.rect = new_sur.get_rect() + self.rect.center = origin_center + self.draw_pos = self.rect.topleft + + def turn_left(self): + if self.is_turn_left: + return + + self.rot += self.rot_speed + self.last_turn_frame = self.used_frame + + self.is_turn_left = True + self.is_turn_right = False + + def turn_right(self): + if self.is_turn_right: + return + + self.rot -= self.rot_speed + self.last_turn_frame = self.used_frame + + self.is_turn_left = False + self.is_turn_right = True + + def get_rot(self): + if self.id == 2: + return (self.rot + 180) % 360 + return self.rot + + def get_obj_progress_data(self) -> dict: + if not self.is_alive: + return {} + image_data = create_image_view_data( + f"{self.id}P_gun", *self.draw_pos, *self.origin_size, self.angle + ) + return image_data + + def get_obj_init_data(self) -> list: + img_data = { + "1P_gun": "https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/1P_gun.svg", + "2P_gun": "https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/2P_gun.svg", + } + image_init_data = [] + for id, url in img_data.items(): + image_init_data.append( + create_asset_init_data( + id, + self.origin_size[0], + self.origin_size[1], + path.join(IMAGE_DIR, f"{id}.png"), + url, + ) + ) + return image_init_data diff --git a/TankMan/src/Player.py b/TankMan/src/Player.py new file mode 100644 index 0000000..b98954c --- /dev/null +++ b/TankMan/src/Player.py @@ -0,0 +1,325 @@ +from os import path +import random +import pygame.draw +from mlgame.utils.enum import get_ai_name +from mlgame.view.view_model import create_asset_init_data, create_image_view_data, create_rect_view_data +from .env import TURN_LEFT_CMD, TURN_RIGHT_CMD, FORWARD_CMD, BACKWARD_CMD, \ + AIM_LEFT_CMD, AIM_RIGHT_CMD, SHOOT, SHOOT_COOLDOWN, IMAGE_DIR, ORANGE, BLUE, IS_DEBUG +from .Gun import Gun + +Vec = pygame.math.Vector2 + + +class Player(pygame.sprite.Sprite): + def __init__(self, construction, **kwargs): + super().__init__() + """ + 初始化玩家資料 + construction可直接由TiledMap打包地圖資訊後傳入 + :param construction: + :param kwargs: + """ + self.id = construction["_id"] + self.no = construction["_no"] + self.rect = pygame.Rect(construction["_init_pos"], construction["_init_size"]) + self.play_rect_area = kwargs["play_rect_area"] + self.origin_xy = self.rect.topleft + self.origin_center = self.rect.center + self.origin_size = (self.rect.width, self.rect.height) + self.original_rect = self.rect.copy() + self.draw_pos = self.rect.topleft + self.surface = pygame.Surface(self.origin_size) + self.angle = 0 + self.score = 0 + self.used_frame = 0 + self.last_shoot_frame = 0 + self.lives = 3 + self.power = 10 + self.vel = Vec(0, 0) + + self.speed = 8 + self.sqrt2 = 1.414 + # TODO refactor use vel + self.move_dict = {"left_up": Vec(-self.speed/self.sqrt2, -self.speed/self.sqrt2), + "right_up": Vec(self.speed/self.sqrt2, -self.speed/self.sqrt2), + "left_down": Vec(-self.speed/self.sqrt2, self.speed/self.sqrt2), + "right_down": Vec(self.speed/self.sqrt2, self.speed/self.sqrt2), + "left": Vec(-self.speed, 0), "right": Vec(self.speed, 0), "up": Vec(0, -self.speed), + "down": Vec(0, self.speed)} + self.rot = 0 + self.last_shoot_frame = self.used_frame + self.last_turn_frame = self.used_frame + self.rot_speed = 45 + self.oil = 100 + self.is_alive = True + self.is_shoot = False + self.is_forward = False + self.is_backward = False + self.is_turn_right = False + self.is_turn_left = False + self.collided = False + self.action_history = [] + self.act_cd = kwargs["act_cd"] + self.quadrant = 0 + + self.gun = Gun(self.id, self.rect.topleft, (self.rect.width, self.rect.height), **kwargs) + + self.calculate_quadrant() + self.pre_rect = self.rect + + def calculate_quadrant(self): + mid_x = self.play_rect_area.width // 2 + mid_y = (self.play_rect_area.height - 100) // 2 + self.quadrant = ( + 1 if self.rect.x >= mid_x and self.rect.y < mid_y else + 2 if self.rect.x < mid_x and self.rect.y < mid_y else + 3 if self.rect.x < mid_x and self.rect.y >= mid_y else + 4 + ) + + def update(self, command: dict): + self.pre_rect = self.rect + self.used_frame += 1 + if self.lives <= 0: + self.is_alive = False + self.gun.is_alive = False + self.lives = 0 + + if not self.is_alive: + self.rect.topleft = Vec(self.play_rect_area.left + self.origin_size[0]*self.no + , self.play_rect_area.top - self.origin_size[1]*2) + return + + self.rotate() + self.gun.update(self.rect.center) + + if not self.act_cd: + self.is_turn_right = False + self.is_turn_left = False + elif self.used_frame - self.last_turn_frame > self.act_cd: + self.is_turn_right = False + self.is_turn_left = False + + self.act(command[get_ai_name(self.no - 1)]) + # check tank if out of playground + self.check_if_outofplayground() + + def check_if_outofplayground(self): + self.rect.clamp_ip(self.play_rect_area) + + def rotate(self): + self.rot = self.rot % 360 + self.angle = 3.14 / 180 * self.rot + new_sur = pygame.transform.rotate(self.surface, self.rot) + origin_center = self.rect.center + self.rect = new_sur.get_rect() + self.rect.center = origin_center + self.draw_pos = self.rect.topleft + + def act(self, commands: list): + if not commands or self.collided: + return None + + # Only one action from the three categories can be executed in one frame + move_flag = False + shoot_flag = False + aim_flag = False + + while commands: + command = commands.pop() + + # Shoot + if not shoot_flag: + if self.power and SHOOT == command: + self.shoot() + + shoot_flag = True + + # Aiming + # TODO: Maybe the oil should be consumed when aiming + if not aim_flag: + if command == AIM_LEFT_CMD: + self.gun.turn_left() + elif command == AIM_RIGHT_CMD: + self.gun.turn_right() + + aim_flag = True + + if self.oil <= 0: + self.oil = 0 + self.lives = 0 + continue + + # Movement + if not move_flag: + if TURN_LEFT_CMD == command and not self.is_turn_left and TURN_RIGHT_CMD != command: + self.oil -= 0.1 + self.turn_left() + self.is_turn_left = True + self.is_forward = False + self.is_backward = False + self.is_turn_right = False + self.action_history.append(TURN_LEFT_CMD) + elif TURN_RIGHT_CMD == command and not self.is_turn_right and TURN_LEFT_CMD != command: + self.oil -= 0.1 + self.turn_right() + self.is_turn_right = True + self.is_forward = False + self.is_backward = False + self.is_turn_left = False + self.action_history.append(TURN_RIGHT_CMD) + elif FORWARD_CMD == command and BACKWARD_CMD != command: + self.oil -= 0.1 + self.forward() + self.is_forward = True + self.is_backward = False + self.is_turn_right = False + self.is_turn_left = False + self.action_history.append(FORWARD_CMD) + elif BACKWARD_CMD == command and FORWARD_CMD != command: + self.oil -= 0.1 + self.backward() + self.is_backward = True + self.is_forward = False + self.is_turn_right = False + self.is_turn_left = False + self.action_history.append(BACKWARD_CMD) + + move_flag = True + + self.action_history = self.action_history[-1:] + + def shoot(self): + if self.last_shoot_frame == 0 or self.used_frame - self.last_shoot_frame > SHOOT_COOLDOWN: + self.last_shoot_frame = self.used_frame + self.power -= 1 + self.is_shoot = True + + def forward(self): + if self.id != 1: + rot = self.rot + 180 + if rot >= 360: + rot -= 360 + else: + rot = self.rot + if rot == 0: + self.rect.center += self.move_dict["left"] + elif rot == 315: + self.rect.center += self.move_dict["left_up"] + elif rot == 270: + self.rect.center += self.move_dict["up"] + elif rot == 225: + self.rect.center += self.move_dict["right_up"] + elif rot == 180: + self.rect.center += self.move_dict["right"] + elif rot == 135: + self.rect.center += self.move_dict["right_down"] + elif rot == 90: + self.rect.center += self.move_dict["down"] + elif rot == 45: + self.rect.center += self.move_dict["left_down"] + + def backward(self): + if self.id != 1: + rot = self.rot + 180 + if rot >= 360: + rot -= 360 + else: + rot = self.rot + if rot == 0: + self.rect.center += self.move_dict["right"] + elif rot == 315: + self.rect.center += self.move_dict["right_down"] + elif rot == 270: + self.rect.center += self.move_dict["down"] + elif rot == 225: + self.rect.center += self.move_dict["left_down"] + elif rot == 180: + self.rect.center += self.move_dict["left"] + elif rot == 135: + self.rect.center += self.move_dict["left_up"] + elif rot == 90: + self.rect.center += self.move_dict["up"] + elif rot == 45: + self.rect.center += self.move_dict["right_up"] + + def turn_left(self): + self.last_turn_frame = self.used_frame + self.rot += self.rot_speed + + def turn_right(self): + self.last_turn_frame = self.used_frame + self.rot -= self.rot_speed + + def collide_with_walls(self): + self.rect = self.pre_rect + + def collide_with_bullets(self): + self.lives -= 1 + + def get_power(self, power: int): + self.power += power + if self.power > 10: + self.power = 10 + elif self.power < 0: + self.power = 0 + + def get_oil(self, oil: int): + self.oil += oil + if self.oil > 100: + self.oil = 100 + elif self.oil < 0: + self.oil = 0 + + def get_rot(self): + if self.id == 2: + return (self.rot + 180) % 360 + return self.rot + + def get_data_from_obj_to_game(self) -> dict: + info = {"id": f"{self.no}P" + , "x": self.rect.x + , "y": self.rect.y + , "speed": self.speed + , "score": self.score + , "power": self.power + , "oil": self.oil + , "lives": self.lives + , "angle": self.get_rot() + , "gun_angle": self.gun.get_rot() + , "cooldown": 0 + if self.last_shoot_frame == 0 + or self.used_frame - self.last_shoot_frame > SHOOT_COOLDOWN + else SHOOT_COOLDOWN - self.used_frame + self.last_shoot_frame, + } + return info + + def get_obj_progress_data(self) -> dict: + if not self.is_alive: + return [] + image_data = create_image_view_data(f"{self.id}P", *self.draw_pos, *self.origin_size, self.angle) + return image_data + + def get_obj_init_data(self) -> list: + img_data = {"1P": "https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/1P_body.svg", + "2P": "https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/2P_body.svg"} + image_init_data = [] + for id, url in img_data.items(): + image_init_data.append(create_asset_init_data(id, self.origin_size[0], self.origin_size[1], + path.join(IMAGE_DIR, f"{id}_body.png"), url)) + return image_init_data + + def get_info_to_game_result(self) -> dict: + info = {"no": f"{self.no}P" + , "score": self.score + , "lives": self.lives + } + if IS_DEBUG: + if self.rect.right > self.play_rect_area.right \ + or self.rect.left < self.play_rect_area.left \ + or self.rect.bottom > self.play_rect_area.bottom \ + or self.rect.top < self.play_rect_area.top: + print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!【OUT】!!!!!!!!!!!!!!!!!!!!!!!!!!!") + else: + print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!【SAFE】!!!!!!!!!!!!!!!!!!!!!!!!!!!") + return info diff --git a/TankMan/src/Station.py b/TankMan/src/Station.py new file mode 100644 index 0000000..8ac842f --- /dev/null +++ b/TankMan/src/Station.py @@ -0,0 +1,65 @@ +from os import path + +import pygame +from mlgame.view.view_model import create_asset_init_data, create_image_view_data + +from .env import IMAGE_DIR, WINDOW_HEIGHT, WINDOW_WIDTH + + +class Station(pygame.sprite.Sprite): + def __init__(self, construction, **kwargs): + super().__init__() + self.id = construction["_id"] + self.rect = pygame.Rect(construction["_init_pos"], construction["_init_size"]) + self.power = kwargs["capacity"] + self.angle = 0 + if self.rect.x >= WINDOW_WIDTH // 2 and self.rect.y < (WINDOW_HEIGHT - 100) // 2: + self.quadrant = 1 + elif self.rect.x < WINDOW_WIDTH // 2 and self.rect.y < (WINDOW_HEIGHT - 100) // 2: + self.quadrant = 2 + elif self.rect.x < WINDOW_WIDTH // 2 and self.rect.y >= (WINDOW_HEIGHT - 100) // 2: + self.quadrant = 3 + else: + self.quadrant = 4 + + self.spawn_cd = kwargs["spawn_cd"] + self.cooldown = 0 + self.is_alive = True + + def update(self): + if not self.is_alive: + self.cooldown -= 1 + if self.cooldown <= 0: + self.is_alive = True + + def collect(self): + self.is_alive = False + self.cooldown = self.spawn_cd + + def get_data_from_obj_to_game(self): + if 5 == self.id: + info = {"id": "oil", "x": self.rect.x, "y": self.rect.y, "power": self.power if self.is_alive else 0} + else: + info = {"id": "bullets", "x": self.rect.x, "y": self.rect.y, "power": self.power if self.is_alive else 0} + return info + + def get_obj_progress_data(self): + if not self.is_alive: + return [] + if 5 == self.id: + return create_image_view_data(f"oil", self.rect.x, self.rect.y + , self.rect.width, self.rect.height, self.angle) + else: + return create_image_view_data(f"bullets", self.rect.x, self.rect.y + , self.rect.width, self.rect.height, self.angle) + + def get_obj_init_data(self): + bullets_id = "bullets" + oil_id = "oil" + bullets_url = f"https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/{bullets_id}.svg" + oil_url = f"https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/{oil_id}.svg" + image_init_data = [create_asset_init_data(bullets_id, self.rect.width, self.rect.height, + path.join(IMAGE_DIR, f"{bullets_id}.png"), bullets_url) + , create_asset_init_data(oil_id, self.rect.width, self.rect.height, + path.join(IMAGE_DIR, f"{oil_id}.png"), oil_url)] + return image_init_data diff --git a/TankMan/src/TeamBattleMode.py b/TankMan/src/TeamBattleMode.py new file mode 100644 index 0000000..99a0270 --- /dev/null +++ b/TankMan/src/TeamBattleMode.py @@ -0,0 +1,508 @@ +import random +import time +import pygame.event +import pygame.event +from src.game_module.SoundController import create_sounds_data, create_bgm_data, SoundController +from src.game_module.TiledMap import create_construction, TiledMap + +from mlgame.game.paia_game import GameResultState, GameStatus +from mlgame.utils.enum import get_ai_name +from mlgame.view.view_model import create_asset_init_data, create_text_view_data, \ + create_rect_view_data, create_line_view_data +from mlgame.view.view_model import create_image_view_data +from .Bullet import Bullet +from .Gun import Gun +from .Player import Player +from .Station import Station +from .Wall import Wall +from .collide_hit_rect import * +from .env import * +from .game_module.fuctions import set_topleft, add_score, set_shoot + + +class TeamBattleMode: + def __init__(self, green_team_num: int, blue_team_num: int, is_manual: bool, frame_limit: int, sound_path: str, + play_rect_area: pygame.Rect): + # init game + pygame.init() + self.sound_path = sound_path + self.green_team_num = green_team_num + self.blue_team_num = blue_team_num if (6 - (green_team_num + blue_team_num)) >= 0 else (6 - green_team_num) + self.map_name = f"map_{green_team_num}_v_{self.blue_team_num}.tmx" if not IS_DEBUG else f"test_map_{green_team_num}_v_{self.blue_team_num}.tmx" + self.map_path = path.join(MAP_DIR, self.map_name) + self.map = TiledMap(self.map_path) + self.scene_width = self.map.map_width + self.scene_height = self.map.map_height + 100 + self.width_center = self.scene_width // 2 + self.height_center = self.scene_height // 2 + self.play_rect_area = play_rect_area + self.used_frame = 0 + self.state = GameResultState.FAIL + self.status = GameStatus.GAME_ALIVE + self.sound_controller = SoundController(sound_path, self.get_sound_data()) + self.sound_controller.play_music(self.get_bgm_data()) + self.frame_limit = frame_limit + self.is_manual = is_manual + self.obj_rect_list = [] + self.team_green_score = 0 + self.team_blue_score = 0 + + # control variables + self.is_invincible = False + self.is_through_wall = False + # initialize sprites group + self.all_sprites = pygame.sprite.Group() + self.players_a = pygame.sprite.Group() + self.players_b = pygame.sprite.Group() + self.all_players = pygame.sprite.Group() + self.guns = pygame.sprite.Group() + self.walls = pygame.sprite.Group() + self.bullets = pygame.sprite.Group() + self.bullet_stations = pygame.sprite.Group() + self.oil_stations = pygame.sprite.Group() + # init players + act_cd = 0 + if self.is_manual: + act_cd = 10 + # init obj data + self.map.add_init_obj_data(PLAYER_1_IMG_NO, Player, act_cd=act_cd, play_rect_area=self.play_rect_area) + self.map.add_init_obj_data(PLAYER_2_IMG_NO, Player, act_cd=act_cd, play_rect_area=self.play_rect_area) + self.map.add_init_obj_data(WALL_IMG_NO, Wall, margin=8, spacing=8) + self.map.add_init_obj_data(BULLET_STATION_IMG_NO, Station, spawn_cd=30, margin=2, spacing=2, capacity=5, + quadrant=1) + self.map.add_init_obj_data(OIL_STATION_IMG_NO, Station, spawn_cd=30, margin=2, spacing=2, capacity=30, + quadrant=1) + # create obj + all_obj = self.map.create_init_obj_dict() + # init players + self.players_a.add(all_obj[PLAYER_1_IMG_NO]) + self.players_b.add(all_obj[PLAYER_2_IMG_NO]) + no = 1 + for player in self.players_a: + player.no = no + no += 1 + for player in self.players_b: + player.no = no + no += 1 + self.all_players.add(*self.players_a, *self.players_b) + self.guns.add(*[player.gun for player in self.all_players]) + self.all_sprites.add(*self.players_a, *self.players_b) + self.all_sprites.add(*[player.gun for player in self.all_players]) + # init walls + self.walls.add(all_obj[WALL_IMG_NO]) + self.all_sprites.add(*self.walls) + # init bullet stations + self.bullet_stations.add(all_obj[BULLET_STATION_IMG_NO]) + self.all_sprites.add(*self.bullet_stations) + # init oil stations + self.oil_stations.add(all_obj[OIL_STATION_IMG_NO]) + self.all_sprites.add(*self.oil_stations) + # init pos list + self.all_pos_list = self.map.all_pos_list + self.empty_quadrant_pos_dict = self.map.empty_quadrant_pos_dict + self.background = [] + for pos in self.all_pos_list: + no = random.randrange(3) + self.background.append( + create_image_view_data(f"floor_{no}", pos[0], pos[1], 50, 50, 0)) + self.obj_list = [self.oil_stations, self.bullet_stations, self.bullets, self.all_players, self.guns, self.walls] + self.background.append(create_image_view_data("border", 0, -50, self.scene_width, WINDOW_HEIGHT, 0)) + # init play get new score time + self.team_green_maxScoreTime = time.time() + self.team_blue_maxScoreTime = time.time() + self.team_green_maxScore = 0 + self.team_blue_maxScore = 0 + self.change_player_pos() + + def update(self, command: dict): + # refactor + self.team_green_score = sum([player.score for player in self.players_a if isinstance(player, Player)]) + self.team_blue_score = sum([player.score for player in self.players_b if isinstance(player, Player)]) + self.used_frame += 1 + self.check_collisions() + self.walls.update() + self.create_bullet(self.all_players) + self.bullets.update() + self.bullet_stations.update() + self.oil_stations.update() + self.all_players.update(command) + self.get_player_end() + if self.used_frame >= self.frame_limit: + self.get_game_end() + + + # check if getting new score + if self.team_green_score > self.team_green_maxScore: + self.team_green_maxScore = self.team_green_score + self.team_green_maxScoreTime = time.time() + + if self.team_blue_score > self.team_blue_maxScore: + self.team_blue_maxScore = self.team_blue_score + self.team_blue_maxScoreTime = time.time() + + def reset(self): + # reset init game + self.__init__(self.green_team_num, self.blue_team_num, self.is_manual, self.frame_limit, self.sound_path, + self.play_rect_area) + # reset player pos + self.change_player_pos() + + def get_player_end(self): + is_alive_team_green = False + is_alive_team_blue = False + for player in self.all_players: + if isinstance(player, Player) and player.is_alive: + if player.no > self.green_team_num and not is_alive_team_blue: + is_alive_team_blue = True + elif player.no <= self.green_team_num: + is_alive_team_green = True + + if not is_alive_team_blue: + self.set_result(GameResultState.FINISH, "GREEN_TEAM_WIN") + elif not is_alive_team_green: + self.set_result(GameResultState.FINISH, "BLUE_TEAM_WIN") + + def get_game_end(self): + if self.team_green_score > self.team_blue_score: + self.set_result(GameResultState.FINISH, "GREEN_TEAM_WIN") + elif self.team_green_score < self.team_blue_score: + self.set_result(GameResultState.FINISH, "BLUE_TEAM_WIN") + else: + # if both the teams have a score of 0 + if self.team_green_maxScore == 0 and self.team_blue_maxScore == 0: + conditions = ["GREEN_TEAM_WIN","BLUE_TEAM_WIN"] + chosen_condition = random.choice(conditions) + self.set_result(GameResultState.FINISH, chosen_condition) + else: + # if both teams have scored and their scores are equal + if self.team_green_maxScoreTime > self.team_blue_maxScoreTime: + self.set_result(GameResultState.FINISH, "BLUE_TEAM_WIN") + else: + self.set_result(GameResultState.FINISH, "GREEN_TEAM_WIN") + + def set_result(self, state: str, status: str): + self.state = state + self.status = status + + def get_player_result(self) -> list: + """Define the end of game will return the player's info for user""" + res = [] + + for player in self.all_players: + if isinstance(player, Player): + if player.no > self.green_team_num: + team_id = "blue" + else: + team_id = "green" + get_res = player.get_info_to_game_result() + + get_res["no"] = f"{team_id}_{player.no}P" + get_res["player"] = f"{player.no}P" + get_res["state"] = self.state + get_res["status"] = self.status + get_res["used_frame"] = self.used_frame + if team_id == "green": + timestamp = self.team_green_maxScoreTime + else: + timestamp = self.team_blue_maxScoreTime + get_res["latestScoreTime"] = "{:.3f}".format(timestamp) + res.append(get_res) + + for player in res: + if player["no"].find("green")!=-1: + player["rank"] = 1 if player["status"] == "GREEN_TEAM_WIN" else 2 + elif player["no"].find("blue")!=-1: + player["rank"] = 1 if player["status"] == "BLUE_TEAM_WIN" else 2 + + sorted_res = sorted(res, key=lambda x: x["rank"]) + + # Result + return sorted_res + + + def check_collisions(self): + if not self.is_through_wall: + collide_with_walls(self.all_players, self.walls) + if not self.is_invincible: + player_score_data = collide_with_bullets(self.all_players, self.bullets, self.green_team_num) + for player, score in player_score_data.items(): + self.add_player_score(player, score) + # TODO refactor stations + + supply_stations = [] + + # Check collision between player and supply stations + supply_stations.extend(collide_with_supply_stations(self.all_players, self.bullet_stations)) + supply_stations.extend(collide_with_supply_stations(self.all_players, self.oil_stations)) + + # Check collision between bullet and supply stations + supply_stations.extend(collide_with_supply_stations(self.bullets, self.bullet_stations)) + supply_stations.extend(collide_with_supply_stations(self.bullets, self.oil_stations)) + + # Update stations position + self.change_obj_pos(supply_stations) + + player_score_data = collide_with_bullets(self.walls, self.bullets) + for player, score in player_score_data.items(): + self.add_player_score(player, score) + + def change_player_pos(self): + for player in self.all_players: + quadrant = player.quadrant + self.empty_quadrant_pos_dict[quadrant].append(player.rect.topleft) + if quadrant == 2 or quadrant == 3: + player.quadrant = random.choice([2, 3]) + else: + player.quadrant = random.choice([1, 4]) + quadrant = player.quadrant + new_pos = self.empty_quadrant_pos_dict[quadrant].pop( + random.randrange(len(self.empty_quadrant_pos_dict[quadrant]))) + set_topleft(player, new_pos) + set_topleft(player.gun, new_pos) + + # TODO move method to Station + def change_obj_pos(self, objs=None): + if objs is None: + return + for obj in objs: + quadrant = obj.quadrant + self.empty_quadrant_pos_dict[quadrant].append(obj.rect.topleft) + if quadrant == 2 or quadrant == 3: + obj.quadrant = random.choice([2, 3]) + else: + obj.quadrant = random.choice([1, 4]) + quadrant = obj.quadrant + new_pos = self.empty_quadrant_pos_dict[quadrant].pop( + random.randrange(len(self.empty_quadrant_pos_dict[quadrant]))) + set_topleft(obj, new_pos) + + def create_bullet(self, sprites: pygame.sprite.Group): + for sprite in sprites: + if not sprite.is_shoot: + continue + self.sound_controller.play_sound("shoot", 0.03, -1) + init_data = create_construction(sprite.id, sprite.no, sprite.rect.center, (BULLET_SIZE[0], BULLET_SIZE[1])) + bullet = Bullet(init_data, rot=sprite.gun.get_rot(), margin=2, spacing=2, bullet_speed=BULLET_SPEED, + bullet_travel_distance=BULLET_TRAVEL_DISTANCE + , play_rect_area=self.play_rect_area) + self.bullets.add(bullet) + self.all_sprites.add(bullet) + set_shoot(sprite, False) + + def get_init_image_data(self): + init_image_data = [] + for i in range(3): + init_image_data.append(create_asset_init_data(f"floor_{i}", 50, 50 + , path.join(IMAGE_DIR, f"grass_{i}.png"), + f"https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/grass_{i}.png")) + for i in range(15): + init_image_data.append(create_asset_init_data(f"hourglass_{i}", 42, 42 + , path.join(IMAGE_DIR, f"hourglass_{i}.png"), + f"https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/hourglass_{i}.png")) + for station in self.bullet_stations: + if isinstance(station, Station): + for data in station.get_obj_init_data(): + init_image_data.append(data) + break + for wall in self.walls: + if isinstance(wall, Wall): + for data in wall.get_obj_init_data(): + init_image_data.append(data) + break + img_id = ["team_a_bullet", "team_b_bullet"] + for id in img_id: + img_url = f"https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/{id}.svg" + bullet_image_init_data = create_asset_init_data(id, BULLET_SIZE[0], BULLET_SIZE[1], + path.join(IMAGE_DIR, f"{id}.png"), img_url) + init_image_data.append(bullet_image_init_data) + border_image_init_data = create_asset_init_data("border", self.scene_width, WINDOW_HEIGHT, + path.join(IMAGE_DIR, "border.png"), + f"https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/border.svg") + init_image_data.append(border_image_init_data) + for player in self.all_players: + if isinstance(player, Player): + data = player.get_obj_init_data() + init_image_data.append(data[0]) + init_image_data.append(data[1]) + break + for gun in self.guns: + if isinstance(gun, Gun): + data = gun.get_obj_init_data() + init_image_data.append(data[0]) + init_image_data.append(data[1]) + break + for i in range(1, 4): + team_a_lives = "team_a_lives" + team_a_lives_image_init_data = create_asset_init_data(f"{team_a_lives}_{i}", LIVES_SIZE[0], LIVES_SIZE[1], + path.join(IMAGE_DIR, f"{team_a_lives}_{i}.png"), + f"https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/{team_a_lives}_{i}.svg") + init_image_data.append(team_a_lives_image_init_data) + team_b_lives = "team_b_lives" + team_b_lives_image_init_data = create_asset_init_data(f"{team_b_lives}_{i}", LIVES_SIZE[0], LIVES_SIZE[1], + path.join(IMAGE_DIR, f"{team_b_lives}_{i}.png"), + f"https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/{team_b_lives}_{i}.svg") + init_image_data.append(team_b_lives_image_init_data) + return init_image_data + + def get_toggle_progress_data(self): + toggle_data = [] + hourglass_index = 0 + if self.is_manual: + hourglass_index = self.used_frame // 10 % 15 + toggle_data.append( + create_image_view_data(image_id=f"hourglass_{hourglass_index}", x=0, y=2, width=20, height=20, angle=0)) + x = 23 + y = 8 + for frame in range((self.frame_limit - self.used_frame) // int((30 * 2))): + toggle_data.append(create_rect_view_data("frame", x, y, 3, 10, RED)) + x += 3.5 + toggle_data.append(create_text_view_data(f"Frame: {self.frame_limit - self.used_frame}", + self.width_center + self.width_center // 2 + 85, 8, RED, + "24px Arial BOLD")) + x = 24 + y = 20 + for score in range(min(self.team_green_score, self.team_blue_score)): + toggle_data.append(create_rect_view_data(name="score", x=x, y=y, width=1, height=10, color=ORANGE)) + x += 1.5 + if x > self.width_center: + if y == 32: + y = 44 + else: + y = 32 + x = 24 + for score in range(abs(self.team_green_score - self.team_blue_score)): + if self.team_green_score > self.team_blue_score: + toggle_data.append(create_rect_view_data("score", x, y, 1, 10, DARKGREEN)) + else: + toggle_data.append(create_rect_view_data("score", x, y, 1, 10, BLUE)) + x += 1.5 + if x > self.width_center: + if y == 32: + y = 44 + else: + y = 32 + x = 24 + # 1P + x = WINDOW_WIDTH - 125 + y = WINDOW_HEIGHT - 40 + toggle_data.append(create_text_view_data(f"Score: {self.team_green_score}", x, y, DARKGREEN, "24px Arial BOLD")) + # 2P + x = 5 + y = WINDOW_HEIGHT - 40 + toggle_data.append(create_text_view_data(f"Score: {self.team_blue_score}", x, y, BLUE, "24px Arial BOLD")) + for player in self.all_players: + if isinstance(player, Player) and player.is_alive: + # lives + team_id = "team_a_lives" if player.id == 1 else "team_b_lives" + color = DARKGREEN if player.id == 1 else BLUE + x = player.play_rect_area.midbottom[0] + 7 + (player.no - 1) * 60 if player.id == 1 \ + else player.play_rect_area.midbottom[0] - (player.no - self.green_team_num) * 60 + y = player.play_rect_area.height + 73 + toggle_data.append( + create_text_view_data(f"{player.no}P", x - 5, y - 25, color, "22px Arial BOLD")) + for live in range(1, player.lives + 1): + toggle_data.append(create_image_view_data(f"{team_id}_{live}", x, y, LIVES_SIZE[0], LIVES_SIZE[1])) + x += 10 + y -= 10 + return toggle_data + + def get_toggle_with_bias_data(self): + toggle_with_bias_data = [] + color = WHITE + for player in self.all_players: + if isinstance(player, Player) and player.is_alive: + # number + if player.no > self.green_team_num: + color = WHITE + x = player.rect.x + y = player.rect.y - 18 + toggle_with_bias_data.append(create_text_view_data(f"{player.no}P", x, y, color, "16px Arial BOLD")) + team_id = "team_a" + if player.no > self.green_team_num: + team_id = "team_b" + # oil + y = player.rect.bottom + toggle_with_bias_data.append( + create_rect_view_data(f"{team_id}_oil", x, y, int(player.oil * 0.5), 8, ORANGE)) + # power + y = player.rect.bottom + 10 + for power in range(player.power): + toggle_with_bias_data.append(create_rect_view_data(f"{team_id}_power", x + 1, y, 3, 8, BLUE)) + x += 5 + + return toggle_with_bias_data + + def get_ai_data_to_player(self): + to_player_data = {} + num = 0 + competitor_info = { + 1: [player.get_data_from_obj_to_game() for player in self.players_a if isinstance(player, Player)] + , 2: [player.get_data_from_obj_to_game() for player in self.players_b if isinstance(player, Player)] + } + walls_info = [wall.get_data_from_obj_to_game() for wall in self.walls if isinstance(wall, Wall)] + bullet_stations_info = [bullst_station.get_data_from_obj_to_game() for bullst_station in self.bullet_stations if + isinstance(bullst_station, Station)] + oil_stations_info = [oil_station.get_data_from_obj_to_game() for oil_station in self.oil_stations if + isinstance(oil_station, Station)] + bullets_info = [bullet.get_data_from_obj_to_game() for bullet in self.bullets if + isinstance(bullet, Bullet)] + for player in self.players_a: + if isinstance(player, Player): + to_game_data = player.get_data_from_obj_to_game() + to_game_data["used_frame"] = self.used_frame + to_game_data["status"] = self.status + to_game_data["teammate_info"] = competitor_info[1] + to_game_data["competitor_info"] = competitor_info[2] + to_game_data["walls_info"] = walls_info + to_game_data["bullets_info"] = bullets_info + to_game_data["bullet_stations_info"] = bullet_stations_info + to_game_data["oil_stations_info"] = oil_stations_info + to_player_data[get_ai_name(num)] = to_game_data + num += 1 + for player in self.players_b: + if isinstance(player, Player): + to_game_data = player.get_data_from_obj_to_game() + to_game_data["used_frame"] = self.used_frame + to_game_data["status"] = self.status + to_game_data["teammate_info"] = competitor_info[2] + to_game_data["competitor_info"] = competitor_info[1] + to_game_data["walls_info"] = walls_info + to_game_data["bullets_info"] = bullets_info + to_game_data["bullet_stations_info"] = bullet_stations_info + to_game_data["oil_stations_info"] = oil_stations_info + to_player_data[get_ai_name(num)] = to_game_data + num += 1 + + return to_player_data + + def get_bgm_data(self): + return create_bgm_data("BGM.ogg", 0.1) + + def get_sound_data(self): + return [create_sounds_data("shoot", "shoot.wav") + , create_sounds_data("touch", "touch.wav")] + + def add_player_score(self, player_no: int, score: int): + if not player_no or not score: + return + for player in self.all_players: + if isinstance(player, Player) and player_no == player.no and player.lives >= 0: + add_score(player, score) + + def debugging(self, is_debug: bool): + self.obj_rect_list = [] + if not is_debug: + return + play_rect_area_points = [self.play_rect_area.topleft, self.play_rect_area.topright + , self.play_rect_area.bottomright, self.play_rect_area.bottomleft + , self.play_rect_area.topleft] + + for sprite in self.all_sprites: + if isinstance(sprite, pygame.sprite.Sprite): + top_left = sprite.rect.topleft + points = [top_left, sprite.rect.topright, sprite.rect.bottomright + , sprite.rect.bottomleft, top_left] + for index in range(len(points) - 1): + self.obj_rect_list.append(create_line_view_data("rect", *points[index], *points[index + 1], RED)) + self.obj_rect_list.append(create_line_view_data("play_rect_area", *play_rect_area_points[index] + , *play_rect_area_points[index + 1], RED)) diff --git a/TankMan/src/Wall.py b/TankMan/src/Wall.py new file mode 100644 index 0000000..e098f8b --- /dev/null +++ b/TankMan/src/Wall.py @@ -0,0 +1,41 @@ +from os import path + +import pygame +from mlgame.view.view_model import create_asset_init_data, create_image_view_data + +from .env import IMAGE_DIR, WALL_LIVE + + +class Wall(pygame.sprite.Sprite): + def __init__(self, construction, **kwargs): + super().__init__() + self.id = construction["_id"] + self.no = 0 + self.rect = pygame.Rect(construction["_init_pos"], construction["_init_size"]) + self.angle = 0 + self.is_alive = True + self.lives = WALL_LIVE + + def update(self, *args, **kwargs) -> None: + if self.lives <= 0: + self.kill() + + def collide_with_bullets(self): + if self.lives > 0: + self.lives -= 1 + + def get_data_from_obj_to_game(self): + info = {"id": f"wall_{self.lives}", "x": self.rect.x, "y": self.rect.y, "lives": self.lives} + return info + + def get_obj_progress_data(self): + return create_image_view_data(f"wall_{self.lives}", self.rect.x, self.rect.y + , self.rect.width, self.rect.height, self.angle) + + def get_obj_init_data(self): + image_init_data = [] + for i in range(1, self.lives+1): + image_init_data.append(create_asset_init_data(f"wall_{i}", self.rect.width, self.rect.height, + path.join(IMAGE_DIR, f"wall_{min(i,3)}.png"), + f"https://raw.githubusercontent.com/Jesse-Jumbo/TankMan/main/asset/image/wall_{min(i,3)}.png")) + return image_init_data diff --git a/TankMan/src/__init__.py b/TankMan/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/TankMan/src/collide_hit_rect.py b/TankMan/src/collide_hit_rect.py new file mode 100644 index 0000000..f71a861 --- /dev/null +++ b/TankMan/src/collide_hit_rect.py @@ -0,0 +1,58 @@ +from typing import Optional +import pygame.sprite + +from src.Player import Player +from src.Bullet import Bullet +from src.Wall import Wall + + +def collide_with_walls(group1: pygame.sprite.Group, group2: pygame.sprite.Group): + hits = pygame.sprite.groupcollide(group1, group2, False, False, pygame.sprite.collide_rect_ratio(0.8)) + for sprite, walls in hits.items(): + sprite.collide_with_walls() + + +def collide_with_bullets(group1: pygame.sprite.Group, group2: pygame.sprite.Group, green_team_num: Optional[int] = None): + hits = pygame.sprite.groupcollide(group1, group2, False, False, pygame.sprite.collide_rect_ratio(0.8)) + player_score_data = {} + for sprite, bullets in hits.items(): + for bullet in bullets: + if bullet.no != sprite.no and sprite.lives > 0: + bullet.kill() + + if isinstance(sprite, Player): + assert green_team_num is not None + if (bullet.no - 1) // green_team_num == (sprite.no - 1) // green_team_num: + # -20 for friendly damage + score = -20 + else: + score = 20 + elif isinstance(sprite, Wall): + score = 1 + if sprite.lives == 1: + score += 5 + else: + continue + + sprite.collide_with_bullets() + + if player_score_data.get(bullet.no) is None: + player_score_data[bullet.no] = 0 + player_score_data[bullet.no] += score + return player_score_data + + +def collide_with_supply_stations(sprites: pygame.sprite.Group, supply_stations: pygame.sprite.Group): + hits = pygame.sprite.groupcollide(sprites, supply_stations, False, False, pygame.sprite.collide_rect_ratio(0.8)) + for sprite, supply_station in hits.items(): + if isinstance(sprite, Player): + if supply_station[0].id == 5: + sprite.get_oil(supply_station[0].power) + else: + sprite.get_power(supply_station[0].power) + elif isinstance(sprite, Bullet): + sprite.kill() + + supply_station[0].collect() + + return [supply_station[0] for supply_station in hits.values()] diff --git a/TankMan/src/env.py b/TankMan/src/env.py new file mode 100644 index 0000000..00f422f --- /dev/null +++ b/TankMan/src/env.py @@ -0,0 +1,85 @@ +from os import path + +import pygame + +IS_DEBUG = False +# TODO remove width and height setting +'''width and height''' +WINDOW_WIDTH = 1000 +WINDOW_HEIGHT = 700 + +'''environment data''' +FPS = 30 +SHOOT_COOLDOWN = 15 + +'''color''' +BLACK = "#000000" +WHITE = "#ffffff" +RED = "#ff0000" +YELLOW = "#ffff00" +GREEN = "#00ff00" +DARKGREEN = "#006400" +GREY = "#8c8c8c" +BLUE = "#0000ff" +LIGHT_BLUE = "#21A1F1" +CYAN_BLUE = "#00FFFF" +PINK = "#FF00FF" +DARKGREY = "#282828" +LIGHTGREY = "#646464" +BROWN = "#643705" +FOREST = "#22390A" +MAGENTA = "#FF00FF" +MEDGRAY = "#4B4B4B" +ORANGE = "#FFA500" + +'''command''' +TURN_LEFT_CMD = "TURN_LEFT" +TURN_RIGHT_CMD = "TURN_RIGHT" +FORWARD_CMD = "FORWARD" +BACKWARD_CMD = "BACKWARD" +AIM_LEFT_CMD = "AIM_LEFT" +AIM_RIGHT_CMD = "AIM_RIGHT" +SHOOT = "SHOOT" + +'''data path''' +GAME_DIR = path.dirname(__file__) +IMAGE_DIR = path.join(GAME_DIR, "..", "asset", "image") +SOUND_DIR = path.join(GAME_DIR, "..", "asset", "sound") +MAP_DIR = path.join(GAME_DIR, "..", "asset", 'maps') + +'''BG View''' +TITLE = "TankMan!" +BG_COLOR = DARKGREY +TILE_X_SIZE = 50 +TILE_Y_SIZE = 50 +TILE_SIZE = 50 +TEXT_SIZE = 100 + +'''object size''' +ALL_OBJECT_SIZE = pygame.Rect(0, 0, 50, 50) +BULLET_SIZE = (13, 16) +LIVES_SIZE = (30, 25) + +"""all setting""" +DOWN_IMG = 'down' +RIGHT_IMG = 'right' +UP_IMG = 'up' +LEFT_IMG = 'left' + +"""collide setting""" +WITH_PLAYER = 'player' + +"""map data numbers""" +PLAYER_1_IMG_NO = 1 +PLAYER_2_IMG_NO = 2 +WALL_IMG_NO = 3 +BULLET_STATION_IMG_NO = 4 +OIL_STATION_IMG_NO = 5 +WALL_LIVE = 4 +BULLET_SPEED = 30 +BULLET_TRAVEL_DISTANCE = 300 + +"""music""" +BGM = 'background_music.ogg/.wav/.mp3' +MENU_SND = 'MenuTheme.ogg/.wav/.mp3' + diff --git a/TankMan/src/game_module/SoundController.py b/TankMan/src/game_module/SoundController.py new file mode 100644 index 0000000..70ad78b --- /dev/null +++ b/TankMan/src/game_module/SoundController.py @@ -0,0 +1,44 @@ +from os import path + +import pygame.mixer + + +def create_sounds_data(id: str, name: str): + return { + "_id": id + , "_name": name + } + + +def create_bgm_data(name: str, volume: float): + return { + "_name": name + , "_volume": volume + } + + +class SoundController: + def __init__(self, sound_path: str, sounds_data_list: list): + self._sound_path = sound_path + if not self._sound_path: + return + self._sounds_obj = {} + pygame.mixer.init() + for sounds_data in sounds_data_list: + sound_data = path.join(self._sound_path, sounds_data["_name"]) + self._sounds_obj[sounds_data["_id"]] = pygame.mixer.Sound(sound_data) + + def play_music(self, bgm_data: dict) -> None: + if not self._sound_path: + return + pygame.mixer.init() + pygame.mixer.music.load(path.join(self._sound_path, bgm_data["_name"])) + pygame.mixer.music.set_volume(bgm_data["_volume"]) + pygame.mixer.music.play(-1) + + def play_sound(self, id: str, volume: float, maz_time: int) -> None: + if not self._sound_path: + return + sound_obj = self._sounds_obj[id] + sound_obj.set_volume(volume) + sound_obj.play(maxtime=maz_time) diff --git a/TankMan/src/game_module/TiledMap.py b/TankMan/src/game_module/TiledMap.py new file mode 100644 index 0000000..7652b5d --- /dev/null +++ b/TankMan/src/game_module/TiledMap.py @@ -0,0 +1,68 @@ +import pytmx + + +def create_construction(_id: int or str, _no: int, _init_pos: tuple, _init_size: tuple): + return { + "_id": _id + , "_no": _no + , "_init_pos": _init_pos + , "_init_size": _init_size + } + + +# Map 讀取地圖資料 +class TiledMap: + def __init__(self, filepath: str): + tm = pytmx.TiledMap(filepath) + self.tile_width = tm.tilewidth + self.tile_height = tm.tileheight + self.width = tm.width + self.height = tm.height + self.map_width = self.tile_width * self.width + self.map_height = self.tile_height * self.height + self.tmx_data = tm + self._is_record = False + self.all_pos_list = [] + self.empty_pos_list = [] + self.empty_quadrant_pos_dict = {1: [], 2: [], 3: [], 4: []} + self.all_obj_data_dict = {} + # TODO refactor + self.all_obj = {} + + def add_init_obj_data(self, img_id: int, cls, **kwargs): + obj_data = {img_id: {"cls": cls, + "kwargs": kwargs + } + } + self.all_obj_data_dict.update(obj_data) + self.all_obj[img_id] = [] + + def create_init_obj_dict(self) -> dict: + obj_no = 0 + for layer in self.tmx_data.visible_layers: + for x, y, gid, in layer: + if isinstance(layer, pytmx.TiledTileLayer): + pos = (x * self.tile_width, y * self.tile_height) + if not self._is_record: + self.all_pos_list.append(pos) + if not self._is_record and not gid: # 0代表空格,無圖塊 + self.empty_pos_list.append(pos) + if pos[0] >= self.map_width // 2 and pos[1] < self.map_height // 2: + self.empty_quadrant_pos_dict[1].append(pos) + elif pos[0] < self.map_width // 2 and pos[1] < self.map_height // 2: + self.empty_quadrant_pos_dict[2].append(pos) + elif pos[0] < self.map_width // 2 and pos[1] >= self.map_height // 2: + self.empty_quadrant_pos_dict[3].append(pos) + else: + self.empty_quadrant_pos_dict[4].append(pos) + elif gid: + img_id = layer.parent.tiledgidmap[gid] + kwargs = self.all_obj_data_dict[img_id]["kwargs"] + obj_no += 1 + img_info = {"_id": img_id, "_no": obj_no + , "_init_pos": pos + , "_init_size": (self.tile_width, self.tile_height) + } + self.all_obj[img_id].append(self.all_obj_data_dict[img_id]["cls"](img_info, **kwargs)) + self._is_record = True + return self.all_obj diff --git a/TankMan/src/game_module/__init__.py b/TankMan/src/game_module/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/TankMan/src/game_module/fuctions.py b/TankMan/src/game_module/fuctions.py new file mode 100644 index 0000000..1d3d1f8 --- /dev/null +++ b/TankMan/src/game_module/fuctions.py @@ -0,0 +1,26 @@ +import pygame.sprite + + +def get_size(sprite: pygame.sprite.Sprite): + return sprite.rect.width, sprite.rect.height + + +def set_topleft(sprite: pygame.sprite.Sprite, top_left: tuple): + sprite.rect.topleft = top_left + + +def add_score(sprite: pygame.sprite.Sprite, score: int): + sprite.score += score + + +def set_shoot(sprite: pygame.sprite.Sprite, is_shoot: bool): + sprite.is_shoot = is_shoot + + +def get_sprites_progress_data(sprites: pygame.sprite.Group): + data_list = [] + for sprite in sprites: + data = sprite.get_obj_progress_data() + if data: + data_list.append(data) + return data_list diff --git a/TankMan/src/game_module/test_case.py b/TankMan/src/game_module/test_case.py new file mode 100644 index 0000000..156a1b8 --- /dev/null +++ b/TankMan/src/game_module/test_case.py @@ -0,0 +1,11 @@ +from src.template.Player import Player + + +class TestPlayer(object): + construction = {"_id": 0, "_no": 0, "x": 0, "y": 0, "width": 60, "height": 60} + player = Player(construction) + + def test_get_xy_pos(self): + assert type(self.player.get_xy_pos()) == tuple + assert type(self.player.get_xy_pos()[0]) == int + assert type(self.player.get_xy_pos()[1]) == int diff --git a/TankMan/test/__init__.py b/TankMan/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/TankMan/test/test_case.py b/TankMan/test/test_case.py new file mode 100644 index 0000000..1e1dbda --- /dev/null +++ b/TankMan/test/test_case.py @@ -0,0 +1,242 @@ +from os import path + +from mlgame.view.view_model import create_asset_init_data, create_image_view_data +from TankBattleMode import TankBattleMode +from TankPlayer import TankPlayer +from env import MAP_DIR + + +class TestTankBattleMode(object): + map_path = path.join(MAP_DIR, "map_00.tmx") + mode = TankBattleMode(map_path, 1200, True) + + def test_calculate_score_type(self): + assert type(self.mode.calculate_score()) == tuple + assert type(self.mode.calculate_score()[0]) == int + assert type(self.mode.calculate_score()[1]) == int + + def test_is_list_type_of_get_1P_command(self): + assert type(self.mode.get_1P_command()) == list + + def test_is_list_type_of_get_2P_command(self): + assert type(self.mode.get_2P_command()) == list + + def test_draw_sprite_data(self): + sprite_data = self.mode.draw_sprite_data() + image_init_data_template = create_image_view_data("1P", 0, 0, 60, 60, 0) + for data in sprite_data: + assert data.keys() == image_init_data_template.keys() + for key in data.keys(): + assert type(data[key]) == type(image_init_data_template[key]) + + +class TestTankPlayer(object): + construction = {"_id": 1, "_no": 0, "x": 0, "y": 0, "width": 60, "height": 60} + player = TankPlayer(construction) + + # TODO how to test update + def test_update(self): + pass + + # TODO how to test rotate + def test_rotate(self): + pass + + def get_shoot_info(self): + return {"id": 0, "center_pos": (0, 0), "rot": 0} + + def test_get_player_shoot_info(self): + shoot_info = self.player.create_shoot_info() + assert shoot_info.keys() == self.get_shoot_info().keys() + for key in shoot_info.keys(): + assert type(shoot_info[key]) == type(self.get_shoot_info()[key]) + + def test_arg(self): + assert self.player.origin_size == (60, 60) + assert self.player.speed == 8 + assert type(self.player.angle) == int + assert type(self.player.score) == int + assert type(self.player.used_frame) == int + assert type(self.player.rot) == int + assert self.player.rot_speed == 45 + assert 100 >= self.player.shield > 0 + assert 10 >= self.player.power > 0 + assert 100 >= self.player.oil > 0 + assert type(self.player.last_turn_frame) == int + assert type(self.player.is_shoot) == bool + assert self.player.is_alive + assert type(self.player.is_turn) == bool + assert type(self.player.is_forward) == bool + assert type(self.player.is_backward) == bool + + def test_move_arg(self): + move = {"left_up": (-self.player.speed, -self.player.speed), + "right_up": (self.player.speed, -self.player.speed), + "left_down": (-self.player.speed, self.player.speed), + "right_down": (self.player.speed, self.player.speed), + "left": (-self.player.speed, 0), "right": (self.player.speed, 0), "up": (0, -self.player.speed), + "down": (0, self.player.speed)} + assert self.player.move_dict == move + + def test_act(self): + # TODO 增加限制type + # TODO how test shoot act + self.player.act(["SHOOT"]) + # assert self.player.is_shoot and self.player.power == 9 and self.player.last_shoot_frame == 50 + self.player.act(["TURN_LEFT"]) + assert self.player.is_turn and round(self.player.oil, 1) == 99.9 + self.player.act(["TURN_RIGHT"]) + assert self.player.is_turn and round(self.player.oil, 1) == 99.8 + self.player.act(["FORWARD"]) + assert self.player.is_forward and not self.player.is_backward and round(self.player.oil, 1) == 99.7 + self.player.act(["BACKWARD"]) + assert self.player.is_backward and not self.player.is_forward and round(self.player.oil, 1) == 99.6 + + def go_straight(self, forward_or_backward: str): + self.player.rot = 0 + self.player.hit_rect.center = self.player.origin_center + if forward_or_backward == "forward": + self.player.forward() + else: + self.player.backward() + return self.player.origin_center, self.player.hit_rect.center + + # TODO how better + def test_go_straight(self): + speed = self.player.speed + origin_center, now_center = self.go_straight("forward") + assert (origin_center[0]-speed, origin_center[1]) == now_center + origin_center, now_center = self.go_straight("backward") + assert (origin_center[0]+speed, origin_center[1]) == now_center + + def turn(self, right_or_left: str, is_turn: bool): + origin_rot = self.player.rot + self.player.is_turn = is_turn + self.player.last_turn_frame = 500 + if right_or_left == "right": + self.player.turn_right() + else: + self.player.turn_left() + return self.player.last_turn_frame, origin_rot, self.player.rot, self.player.is_turn + + # TODO how better + def test_turn_method(self): + turn_cd, origin_rot, new_rot, is_turn = self.turn("right", True) + assert turn_cd == 500 and new_rot == origin_rot and is_turn + turn_cd, origin_rot, new_rot, is_turn = self.turn("right", False) + assert turn_cd == 0 and new_rot == origin_rot-self.player.rot_speed and is_turn + turn_cd, origin_rot, new_rot, is_turn = self.turn("left", True) + assert turn_cd == 500 and new_rot == origin_rot and is_turn + turn_cd, origin_rot, new_rot, is_turn = self.turn("left", False) + assert turn_cd == 0 and new_rot == origin_rot+self.player.rot_speed and is_turn + + def collide_with_walls(self, is_forward: bool): + self.player.rot = 0 + self.player.hit_rect.center = (100, 100) + old_center = self.player.hit_rect.center + self.player.is_forward = is_forward + self.player.collide_with_walls() + return old_center, self.player.hit_rect.center + + def test_collide_with_walls(self): + speed = self.player.speed + old_center, new_center = self.collide_with_walls(is_forward=True) + assert (old_center[0]+speed, old_center[1]) == new_center + old_center, new_center = self.collide_with_walls(is_forward=False) + assert (old_center[0]-speed, old_center[1]) == new_center + + def collide_with_bullets(self, shield: int, lives: int): + self.player.shield = shield + self.player.lives = lives + self.player.collide_with_bullets() + return {"shield": self.player.shield, "lives": self.player.lives, "pos": self.player.rect.center} + + def test_collide_with_bullets(self): + self.player.rect.center = (50, 50) + self.collide_with_bullets(1, 1) + assert self.player.shield == 100 + assert self.player.lives == 0 + assert self.player.rect.center == self.player.origin_center + self.player.rect.center = (50, 50) + self.collide_with_bullets(1, 2) + assert self.player.shield == 100 + assert self.player.lives == 1 + assert self.player.rect.center == self.player.origin_center + self.player.rect.center = (50, 50) + self.collide_with_bullets(100, 2) + assert 100 > self.player.shield > 89 + assert self.player.lives == 2 + assert self.player.rect.center == (50, 50) + assert self.player.rect.center != self.player.origin_center + + def test_get_power(self): + self.player.get_power(-10) + assert self.player.power == 0 + self.player.get_power(10) + assert self.player.power == 10 + self.player.get_power(-11) + assert self.player.power == 0 + self.player.get_power(11) + assert self.player.power == 10 + self.player.get_power(-5) + assert self.player.power == 5 + self.player.get_power(3) + assert self.player.power == 8 + + def test_get_oil(self): + self.player.get_oil(-100) + assert self.player.oil == 0 + self.player.get_oil(100) + assert self.player.oil == 100 + self.player.get_oil(-110) + assert self.player.oil == 0 + self.player.get_oil(110) + assert self.player.oil == 100 + self.player.get_oil(-50) + assert self.player.oil == 50 + self.player.get_oil(30) + assert self.player.oil == 80 + + def get_info(self): + return {"id": f"{0}P", + "x": 0, + "y": 0, + "speed": 0, + "score": 0, + "power": 0, + "oil": 0, + "shield": 0, + "lives": 0 + } + + def test_get_player_info(self): + info = self.player.get_info() + assert info.keys() == self.get_info().keys() + for key in info.keys(): + assert type(info[key]) == type(self.get_info()[key]) + + def get_result(self): + return {"id": f"{0}P", "x": 0, "y": 0, "score": 0, "shield": 0, "lives": 0} + + def test_get_result(self): + result = self.player.get_result() + assert result.keys() == self.get_result().keys() + for key in result.keys(): + assert type(result[key]) == type(self.get_result()[key]) + + def get_image_data(self): + return {ID: f"{0}P", X: 0, Y: 0, WIDTH: 0, HEIGHT: 0, ANGLE: 0} + + def test_get_image_data(self): + image_data = self.player.get_image_data() + assert image_data.keys() == self.get_image_data().keys() + for key in image_data.keys(): + assert type(image_data[key]) == type(self.get_image_data()[key]) + + def test_get_image_init_data(self): + image_init_data = self.player.get_image_init_data() + image_init_data_template = create_asset_init_data("1P", 60, 60, "path", "url") + for data in image_init_data: + assert data.keys() == image_init_data_template.keys() + for key in data.keys(): + assert type(data[key]) == type(image_init_data_template[key]) diff --git a/justfile b/justfile new file mode 100644 index 0000000..47b86d5 --- /dev/null +++ b/justfile @@ -0,0 +1,19 @@ +test: + just release + ./test.sh +clean: + rm -r output1/* output2/* +train epoch: + just build + ./train.sh {{epoch}} +init: + just build + MODEL_PATH="output1" ./train + MODEL_PATH="output2" ./train +build: + cd tank-rust && cargo build --release --lib --bin tank-rust + cp tank-rust/target/release/tank-rust train + cp tank-rust/target/release/libtank_rust.so . +release: + cd tank-rust && cargo build --release --lib --no-default-features + cp tank-rust/target/release/libtank_rust.so . \ No newline at end of file diff --git a/ml/collect1.py b/ml/collect1.py new file mode 100644 index 0000000..2cda15d --- /dev/null +++ b/ml/collect1.py @@ -0,0 +1,187 @@ +""" +The template of the main script of the machine learning process +""" + +from ctypes import * + +import pygame + + +class Player(Structure): + _fields_ = [ + ("x", c_int32), + ("y", c_int32), + ("speed", c_int32), + ("score", c_int32), + ("power", c_int32), + ("oil", c_float), + ("lives", c_int32), + ("angle", c_int32), + ("gun_angle", c_int32), + ("cooldown", c_int32), + ] + + def from_dict(self, d: dict): + self.x = d["x"] + self.y = d["y"] + self.speed = d["speed"] + self.score = d["score"] + self.power = d["power"] + self.oil = d["oil"] + self.lives = d["lives"] + self.angle = d["angle"] + self.gun_angle = d["gun_angle"] + self.cooldown = d["cooldown"] + return self + + +class Bullet(Structure): + _fields_ = [("x", c_int32), ("y", c_int32)] + + def from_dict(self, d: dict): + self.x = d["x"] + self.y = d["y"] + return self + + +class Station(Structure): + _fields_ = [ + ("x", c_int32), + ("y", c_int32), + ("power", c_int32), + ] + + def from_dict(self, d: dict): + self.x = d["x"] + self.y = d["y"] + self.power = d["power"] + return self + + +class Wall(Structure): + _fields_ = [ + ("x", c_int32), + ("y", c_int32), + ("lives", c_int32), + ] + + def from_dict(self, d: dict): + self.x = d["x"] + self.y = d["y"] + self.lives = d["lives"] + return self + + +class Info(Structure): + _fields_ = [ + ("player", POINTER(Player)), + ("teammates", POINTER(Player)), + ("teammates_len", c_uint32), + ("enemies", POINTER(Player)), + ("enemies_len", c_uint32), + ("bullets", POINTER(Bullet)), + ("bullet_len", c_uint32), + ("bullet_stations", POINTER(Station)), + ("bullet_stations_len", c_uint32), + ("oil_stations", POINTER(Station)), + ("oil_stations_len", c_uint32), + ("walls", POINTER(Wall)), + ("walls_len", c_uint32), + ] + + def from_dict(self, d: dict): + self.player = pointer(Player().from_dict(d)) + + self.teammates = (Player * len(d["teammate_info"]))() + for i, t in enumerate(d["teammate_info"]): + self.teammates[i] = Player().from_dict(t) + self.teammates_len = len(d["teammate_info"]) + + self.enemies = (Player * len(d["competitor_info"]))() + for i, e in enumerate(d["competitor_info"]): + self.enemies[i] = Player().from_dict(e) + self.enemies_len = len(d["competitor_info"]) + + self.bullets = (Bullet * len(d["bullets_info"]))() + for i, b in enumerate(d["bullets_info"]): + self.bullets[i] = Bullet().from_dict(b) + self.bullet_len = len(d["bullets_info"]) + + self.bullet_stations = (Station * len(d["bullet_stations_info"]))() + for i, b in enumerate(d["bullet_stations_info"]): + self.bullet_stations[i] = Station().from_dict(b) + self.bullet_stations_len = len(d["bullet_stations_info"]) + + self.oil_stations = (Station * len(d["oil_stations_info"]))() + for i, o in enumerate(d["oil_stations_info"]): + self.oil_stations[i] = Station().from_dict(o) + self.oil_stations_len = len(d["oil_stations_info"]) + + self.walls = (Wall * len(d["walls_info"]))() + for i, w in enumerate(d["walls_info"]): + self.walls[i] = Wall().from_dict(w) + self.walls_len = len(d["walls_info"]) + + return self + + +tank_rs = cdll.LoadLibrary("../libtank_rust.so") +tank_rs.init.argtypes = [c_char_p, c_int32] +tank_rs.init.restype = c_void_p +tank_rs.tick.argtypes = [c_void_p, POINTER(Info)] +tank_rs.tick.restype = c_int32 +tank_rs.flush.argtypes = [c_void_p] + +app = tank_rs.init(c_char_p("../output1".encode()), 10) + + +class MLPlay: + def __init__(self, ai_name, *args, **kwargs): + """ + Constructor + + @param ai_name A string "1P" or "2P" indicates that the `MLPlay` is used by + which side. + """ + self.side = ai_name + print(f"Initial Game {ai_name} ml script") + self.time = 0 + + def update(self, scene_info: dict, keyboard=[], *args, **kwargs): + """ + Generate the command according to the received scene information + """ + if scene_info["status"] != "GAME_ALIVE": + tank_rs.flush(app) + + info = Info().from_dict(scene_info) + + action = tank_rs.tick(app, info) + + command = "" + + if action == 0: + command = "FORWARD" + elif action == 1: + command = "BACKWARD" + elif action == 2: + command = "TURN_RIGHT" + elif action == 3: + command = "TURN_LEFT" + elif action == 4: + command = "AIM_RIGHT" + elif action == 5: + command = "AIM_LEFT" + elif action == 6: + command = "SHOOT" + elif action == 7: + command = "NONE" + + info + return [command] + + def reset(self): + """ + Reset the status + """ + print(f"reset Game {self.side}") diff --git a/ml/collect2.py b/ml/collect2.py new file mode 100644 index 0000000..a5ca329 --- /dev/null +++ b/ml/collect2.py @@ -0,0 +1,187 @@ +""" +The template of the main script of the machine learning process +""" + +from ctypes import * + +import pygame + + +class Player(Structure): + _fields_ = [ + ("x", c_int32), + ("y", c_int32), + ("speed", c_int32), + ("score", c_int32), + ("power", c_int32), + ("oil", c_float), + ("lives", c_int32), + ("angle", c_int32), + ("gun_angle", c_int32), + ("cooldown", c_int32), + ] + + def from_dict(self, d: dict): + self.x = d["x"] + self.y = d["y"] + self.speed = d["speed"] + self.score = d["score"] + self.power = d["power"] + self.oil = d["oil"] + self.lives = d["lives"] + self.angle = d["angle"] + self.gun_angle = d["gun_angle"] + self.cooldown = d["cooldown"] + return self + + +class Bullet(Structure): + _fields_ = [("x", c_int32), ("y", c_int32)] + + def from_dict(self, d: dict): + self.x = d["x"] + self.y = d["y"] + return self + + +class Station(Structure): + _fields_ = [ + ("x", c_int32), + ("y", c_int32), + ("power", c_int32), + ] + + def from_dict(self, d: dict): + self.x = d["x"] + self.y = d["y"] + self.power = d["power"] + return self + + +class Wall(Structure): + _fields_ = [ + ("x", c_int32), + ("y", c_int32), + ("lives", c_int32), + ] + + def from_dict(self, d: dict): + self.x = d["x"] + self.y = d["y"] + self.lives = d["lives"] + return self + + +class Info(Structure): + _fields_ = [ + ("player", POINTER(Player)), + ("teammates", POINTER(Player)), + ("teammates_len", c_uint32), + ("enemies", POINTER(Player)), + ("enemies_len", c_uint32), + ("bullets", POINTER(Bullet)), + ("bullet_len", c_uint32), + ("bullet_stations", POINTER(Station)), + ("bullet_stations_len", c_uint32), + ("oil_stations", POINTER(Station)), + ("oil_stations_len", c_uint32), + ("walls", POINTER(Wall)), + ("walls_len", c_uint32), + ] + + def from_dict(self, d: dict): + self.player = pointer(Player().from_dict(d)) + + self.teammates = (Player * len(d["teammate_info"]))() + for i, t in enumerate(d["teammate_info"]): + self.teammates[i] = Player().from_dict(t) + self.teammates_len = len(d["teammate_info"]) + + self.enemies = (Player * len(d["competitor_info"]))() + for i, e in enumerate(d["competitor_info"]): + self.enemies[i] = Player().from_dict(e) + self.enemies_len = len(d["competitor_info"]) + + self.bullets = (Bullet * len(d["bullets_info"]))() + for i, b in enumerate(d["bullets_info"]): + self.bullets[i] = Bullet().from_dict(b) + self.bullet_len = len(d["bullets_info"]) + + self.bullet_stations = (Station * len(d["bullet_stations_info"]))() + for i, b in enumerate(d["bullet_stations_info"]): + self.bullet_stations[i] = Station().from_dict(b) + self.bullet_stations_len = len(d["bullet_stations_info"]) + + self.oil_stations = (Station * len(d["oil_stations_info"]))() + for i, o in enumerate(d["oil_stations_info"]): + self.oil_stations[i] = Station().from_dict(o) + self.oil_stations_len = len(d["oil_stations_info"]) + + self.walls = (Wall * len(d["walls_info"]))() + for i, w in enumerate(d["walls_info"]): + self.walls[i] = Wall().from_dict(w) + self.walls_len = len(d["walls_info"]) + + return self + + +tank_rs = cdll.LoadLibrary("../libtank_rust.so") +tank_rs.init.argtypes = [c_char_p, c_int32] +tank_rs.init.restype = c_void_p +tank_rs.tick.argtypes = [c_void_p, POINTER(Info)] +tank_rs.tick.restype = c_int32 +tank_rs.flush.argtypes = [c_void_p] + +app = tank_rs.init(c_char_p("../output2".encode()), 10) + + +class MLPlay: + def __init__(self, ai_name, *args, **kwargs): + """ + Constructor + + @param ai_name A string "1P" or "2P" indicates that the `MLPlay` is used by + which side. + """ + self.side = ai_name + print(f"Initial Game {ai_name} ml script") + self.time = 0 + + def update(self, scene_info: dict, keyboard=[], *args, **kwargs): + """ + Generate the command according to the received scene information + """ + if scene_info["status"] != "GAME_ALIVE": + tank_rs.flush(app) + + info = Info().from_dict(scene_info) + + action = tank_rs.tick(app, info) + + command = "" + + if action == 0: + command = "FORWARD" + elif action == 1: + command = "BACKWARD" + elif action == 2: + command = "TURN_RIGHT" + elif action == 3: + command = "TURN_LEFT" + elif action == 4: + command = "AIM_RIGHT" + elif action == 5: + command = "AIM_LEFT" + elif action == 6: + command = "SHOOT" + elif action == 7: + command = "NONE" + + info + return [command] + + def reset(self): + """ + Reset the status + """ + print(f"reset Game {self.side}") diff --git a/ml/test.py b/ml/test.py new file mode 100644 index 0000000..5552372 --- /dev/null +++ b/ml/test.py @@ -0,0 +1,202 @@ +""" +The template of the main script of the machine learning process +""" + +from ctypes import * + +import pygame + + +class Player(Structure): + _fields_ = [ + ("x", c_int32), + ("y", c_int32), + ("speed", c_int32), + ("score", c_int32), + ("power", c_int32), + ("oil", c_float), + ("lives", c_int32), + ("angle", c_int32), + ("gun_angle", c_int32), + ("cooldown", c_int32), + ] + + def from_dict(self, d: dict): + self.x = d["x"] + self.y = d["y"] + self.speed = d["speed"] + self.score = d["score"] + self.power = d["power"] + self.oil = d["oil"] + self.lives = d["lives"] + self.angle = d["angle"] + self.gun_angle = d["gun_angle"] + self.cooldown = d["cooldown"] + return self + + +class Bullet(Structure): + _fields_ = [("x", c_int32), ("y", c_int32)] + + def from_dict(self, d: dict): + self.x = d["x"] + self.y = d["y"] + return self + + +class Station(Structure): + _fields_ = [ + ("x", c_int32), + ("y", c_int32), + ("power", c_int32), + ] + + def from_dict(self, d: dict): + self.x = d["x"] + self.y = d["y"] + self.power = d["power"] + return self + + +class Wall(Structure): + _fields_ = [ + ("x", c_int32), + ("y", c_int32), + ("lives", c_int32), + ] + + def from_dict(self, d: dict): + self.x = d["x"] + self.y = d["y"] + self.lives = d["lives"] + return self + + +class Info(Structure): + _fields_ = [ + ("player", POINTER(Player)), + ("teammates", POINTER(Player)), + ("teammates_len", c_uint32), + ("enemies", POINTER(Player)), + ("enemies_len", c_uint32), + ("bullets", POINTER(Bullet)), + ("bullet_len", c_uint32), + ("bullet_stations", POINTER(Station)), + ("bullet_stations_len", c_uint32), + ("oil_stations", POINTER(Station)), + ("oil_stations_len", c_uint32), + ("walls", POINTER(Wall)), + ("walls_len", c_uint32), + ] + + def from_dict(self, d: dict): + self.player = pointer(Player().from_dict(d)) + + self.teammates = (Player * len(d["teammate_info"]))() + for i, t in enumerate(d["teammate_info"]): + self.teammates[i] = Player().from_dict(t) + self.teammates_len = len(d["teammate_info"]) + + self.enemies = (Player * len(d["competitor_info"]))() + for i, e in enumerate(d["competitor_info"]): + self.enemies[i] = Player().from_dict(e) + self.enemies_len = len(d["competitor_info"]) + + self.bullets = (Bullet * len(d["bullets_info"]))() + for i, b in enumerate(d["bullets_info"]): + self.bullets[i] = Bullet().from_dict(b) + self.bullet_len = len(d["bullets_info"]) + + self.bullet_stations = (Station * len(d["bullet_stations_info"]))() + for i, b in enumerate(d["bullet_stations_info"]): + self.bullet_stations[i] = Station().from_dict(b) + self.bullet_stations_len = len(d["bullet_stations_info"]) + + self.oil_stations = (Station * len(d["oil_stations_info"]))() + for i, o in enumerate(d["oil_stations_info"]): + self.oil_stations[i] = Station().from_dict(o) + self.oil_stations_len = len(d["oil_stations_info"]) + + self.walls = (Wall * len(d["walls_info"]))() + for i, w in enumerate(d["walls_info"]): + self.walls[i] = Wall().from_dict(w) + self.walls_len = len(d["walls_info"]) + + return self + + +tank_rs = cdll.LoadLibrary("../libtank_rust.so") +tank_rs.init.argtypes = [c_char_p, c_int32] +tank_rs.init.restype = c_void_p +tank_rs.tick.argtypes = [c_void_p, POINTER(Info)] +tank_rs.tick.restype = c_int32 +tank_rs.flush.argtypes = [c_void_p] + +app = tank_rs.init(c_char_p("../output2".encode()), 10) + + +class MLPlay: + def __init__(self, ai_name, *args, **kwargs): + """ + Constructor + + @param ai_name A string "1P" or "2P" indicates that the `MLPlay` is used by + which side. + """ + self.side = ai_name + print(f"Initial Game {ai_name} ml script") + self.time = 0 + + def update(self, scene_info: dict, keyboard=[], *args, **kwargs): + """ + Generate the command according to the received scene information + """ + if scene_info["status"] != "GAME_ALIVE": + tank_rs.flush(app) + + command = "command" + + if pygame.K_d in keyboard: + command = "TURN_RIGHT" + elif pygame.K_a in keyboard: + command = "TURN_LEFT" + elif pygame.K_w in keyboard: + command = "FORWARD" + elif pygame.K_s in keyboard: + command = "BACKWARD" + + if pygame.K_q in keyboard: + command = "AIM_LEFT" + elif pygame.K_e in keyboard: + command = "AIM_RIGHT" + + if pygame.K_f in keyboard: + command = "SHOOT" + if command == "command": + info = Info().from_dict(scene_info) + + action = tank_rs.tick(app, info) + if action == 0: + command = "FORWARD" + elif action == 1: + command = "BACKWARD" + elif action == 2: + command = "TURN_RIGHT" + elif action == 3: + command = "TURN_LEFT" + elif action == 4: + command = "AIM_RIGHT" + elif action == 5: + command = "AIM_LEFT" + elif action == 6: + command = "SHOOT" + elif action == 7: + command = "NONE" + + return [command] + + def reset(self): + """ + Reset the status + """ + print(f"reset Game {self.side}") diff --git a/tank-rust/.gitignore b/tank-rust/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/tank-rust/.gitignore @@ -0,0 +1 @@ +/target diff --git a/tank-rust/Cargo.lock b/tank-rust/Cargo.lock new file mode 100644 index 0000000..2da1567 --- /dev/null +++ b/tank-rust/Cargo.lock @@ -0,0 +1,3574 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "ash" +version = "0.37.3+1.3.251" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" +dependencies = [ + "libloading 0.7.4", +] + +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bincode" +version = "2.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f11ea1a0346b94ef188834a65c068a03aec181c94896d481d7a0a40d85b0ce95" +dependencies = [ + "serde", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "burn" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3960b57a6ad4baf54d1dba766965e4559c4b9a8f391107fee5de29db57265840" +dependencies = [ + "burn-core", + "burn-train", +] + +[[package]] +name = "burn-autodiff" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9479c28bdce3f2b1541f0a9215628f6256b5f3d66871192a3c56d55171d28e" +dependencies = [ + "burn-common", + "burn-tensor", + "derive-new", + "log", + "spin", +] + +[[package]] +name = "burn-candle" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d811c54fa6d9beb38808a1aabd9515c39090720cae572d54f25c041b1702e8fd" +dependencies = [ + "burn-tensor", + "candle-core", + "derive-new", + "half", +] + +[[package]] +name = "burn-common" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9540b2f45a2d337220e702d7a87572c8e1c78db91a200b22924a8c4a6e9be4" +dependencies = [ + "async-trait", + "derive-new", + "getrandom", + "rand", + "serde", + "spin", + "uuid", + "web-time", +] + +[[package]] +name = "burn-compute" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e890d8999b25a1a090c2afe198243fc79f0a299efb531a4871c084b0ab9fa11" +dependencies = [ + "burn-common", + "derive-new", + "dirs", + "hashbrown 0.14.5", + "log", + "md5", + "serde", + "serde_json", + "spin", + "web-time", +] + +[[package]] +name = "burn-core" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8af6bc0afe55a57ff0b08f52302df4e3d09f96805a4f1e15c521f1082cb02b4f" +dependencies = [ + "bincode 2.0.0-rc.3", + "burn-autodiff", + "burn-candle", + "burn-common", + "burn-dataset", + "burn-derive", + "burn-ndarray", + "burn-tch", + "burn-tensor", + "burn-wgpu", + "derive-new", + "flate2", + "half", + "hashbrown 0.14.5", + "log", + "num-traits", + "rand", + "rmp-serde", + "serde", + "serde_json", + "spin", +] + +[[package]] +name = "burn-dataset" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3feae7766b56e947d38ac4d6903388270d848609339a147a513145703426f6db" +dependencies = [ + "csv", + "derive-new", + "dirs", + "gix-tempfile", + "image", + "r2d2", + "r2d2_sqlite", + "rand", + "rmp-serde", + "rusqlite", + "sanitize-filename", + "serde", + "serde_json", + "serde_rusqlite", + "strum", + "strum_macros", + "tempfile", + "thiserror", +] + +[[package]] +name = "burn-derive" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8618ac2c171c7054ffd3ce8da15c3d4b11dc805eb393065c74c05882ef79d931" +dependencies = [ + "derive-new", + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "burn-fusion" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d77b882d131a67d15f91b915fb3e0a5add73547e7352310d33c877fbe77c79e" +dependencies = [ + "burn-common", + "burn-tensor", + "derive-new", + "hashbrown 0.14.5", + "log", + "serde", + "spin", +] + +[[package]] +name = "burn-jit" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cb62a93030a690c329b95c01b43e3064a4bd36031e9111d537641d36e42f3ac" +dependencies = [ + "burn-common", + "burn-compute", + "burn-fusion", + "burn-tensor", + "bytemuck", + "derive-new", + "hashbrown 0.14.5", + "log", + "num-traits", + "rand", + "serde", + "spin", + "text_placeholder", +] + +[[package]] +name = "burn-ndarray" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f40bb0b5938937a721045752f1ec1baee8a873429fd17e6e6f2155c6cdf33a" +dependencies = [ + "burn-autodiff", + "burn-common", + "burn-tensor", + "derive-new", + "libm", + "matrixmultiply", + "ndarray", + "num-traits", + "rand", + "rayon", + "spin", +] + +[[package]] +name = "burn-tch" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cb9c2b547499a3d990e93b950965b9a478edfec4a7bf98d5d4412ff8c897129" +dependencies = [ + "burn-tensor", + "half", + "libc", + "rand", + "tch", +] + +[[package]] +name = "burn-tensor" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa19c21f54e1a189be3bbaec45efafdf1c89b2763710b381c9f32ae25e7dbe8" +dependencies = [ + "burn-common", + "derive-new", + "half", + "hashbrown 0.14.5", + "num-traits", + "rand", + "rand_distr", + "serde", +] + +[[package]] +name = "burn-train" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a0014ee82ef967bd82dda378cfaf340f255c39c729e29ac3bc65d3107e4c7ee" +dependencies = [ + "burn-core", + "crossterm", + "derive-new", + "log", + "nvml-wrapper", + "ratatui", + "serde", + "sysinfo", + "systemstat", + "tracing-appender", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "burn-wgpu" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1575890471123109c6aeb725c52ac649fa9e0013e2303f57dc534d5e0cb857e5" +dependencies = [ + "burn-common", + "burn-compute", + "burn-fusion", + "burn-jit", + "burn-tensor", + "bytemuck", + "derive-new", + "futures-intrusive", + "hashbrown 0.14.5", + "log", + "pollster", + "wgpu", +] + +[[package]] +name = "bytemuck" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytesize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "candle-core" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f1b20174c1707e20f4cb364a355b449803c03e9b0c9193324623cf9787a4e00" +dependencies = [ + "byteorder", + "gemm", + "half", + "memmap2", + "num-traits", + "num_cpus", + "rand", + "rand_distr", + "rayon", + "safetensors 0.4.3", + "thiserror", + "yoke", + "zip", +] + +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + +[[package]] +name = "cc" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +dependencies = [ + "jobserver", + "libc", + "once_cell", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "com" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" +dependencies = [ + "com_macros", +] + +[[package]] +name = "com_macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" +dependencies = [ + "com_macros_support", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "com_macros_support" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crossterm" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +dependencies = [ + "bitflags 2.5.0", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "d3d12" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307" +dependencies = [ + "bitflags 2.5.0", + "libloading 0.8.3", + "winapi", +] + +[[package]] +name = "darling" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.65", +] + +[[package]] +name = "darling_macro" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive-new" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dyn-stack" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e53799688f5632f364f8fb387488dd05db9fe45db7011be066fc20e7027f8b" +dependencies = [ + "bytemuck", + "reborrow", +] + +[[package]] +name = "either" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" + +[[package]] +name = "enum-as-inner" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "faster-hex" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" +dependencies = [ + "serde", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "fdeflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "gemm" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab24cc62135b40090e31a76a9b2766a501979f3070fa27f689c27ec04377d32" +dependencies = [ + "dyn-stack", + "gemm-c32", + "gemm-c64", + "gemm-common", + "gemm-f16", + "gemm-f32", + "gemm-f64", + "num-complex", + "num-traits", + "paste", + "raw-cpuid", + "seq-macro", +] + +[[package]] +name = "gemm-c32" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9c030d0b983d1e34a546b86e08f600c11696fde16199f971cd46c12e67512c0" +dependencies = [ + "dyn-stack", + "gemm-common", + "num-complex", + "num-traits", + "paste", + "raw-cpuid", + "seq-macro", +] + +[[package]] +name = "gemm-c64" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbb5f2e79fefb9693d18e1066a557b4546cd334b226beadc68b11a8f9431852a" +dependencies = [ + "dyn-stack", + "gemm-common", + "num-complex", + "num-traits", + "paste", + "raw-cpuid", + "seq-macro", +] + +[[package]] +name = "gemm-common" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2e7ea062c987abcd8db95db917b4ffb4ecdfd0668471d8dc54734fdff2354e8" +dependencies = [ + "bytemuck", + "dyn-stack", + "half", + "num-complex", + "num-traits", + "once_cell", + "paste", + "pulp", + "raw-cpuid", + "rayon", + "seq-macro", + "sysctl", +] + +[[package]] +name = "gemm-f16" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca4c06b9b11952071d317604acb332e924e817bd891bec8dfb494168c7cedd4" +dependencies = [ + "dyn-stack", + "gemm-common", + "gemm-f32", + "half", + "num-complex", + "num-traits", + "paste", + "raw-cpuid", + "rayon", + "seq-macro", +] + +[[package]] +name = "gemm-f32" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9a69f51aaefbd9cf12d18faf273d3e982d9d711f60775645ed5c8047b4ae113" +dependencies = [ + "dyn-stack", + "gemm-common", + "num-complex", + "num-traits", + "paste", + "raw-cpuid", + "seq-macro", +] + +[[package]] +name = "gemm-f64" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa397a48544fadf0b81ec8741e5c0fba0043008113f71f2034def1935645d2b0" +dependencies = [ + "dyn-stack", + "gemm-common", + "num-complex", + "num-traits", + "paste", + "raw-cpuid", + "seq-macro", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gix-features" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d46a4a5c6bb5bebec9c0d18b65ada20e6517dbd7cf855b87dd4bbdce3a771b2" +dependencies = [ + "gix-hash", + "gix-trace", + "libc", +] + +[[package]] +name = "gix-fs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20e86eb040f5776a5ade092282e51cdcad398adb77d948b88d17583c2ae4e107" +dependencies = [ + "gix-features", +] + +[[package]] +name = "gix-hash" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f8cf8c2266f63e582b7eb206799b63aa5fa68ee510ad349f637dfe2d0653de0" +dependencies = [ + "faster-hex", + "thiserror", +] + +[[package]] +name = "gix-tempfile" +version = "11.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388dd29114a86ec69b28d1e26d6d63a662300ecf61ab3f4cc578f7d7dc9e7e23" +dependencies = [ + "dashmap", + "gix-fs", + "libc", + "once_cell", + "parking_lot", + "signal-hook", + "signal-hook-registry", + "tempfile", +] + +[[package]] +name = "gix-trace" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f924267408915fddcd558e3f37295cc7d6a3e50f8bd8b606cee0808c3915157e" + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glow" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gpu-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" +dependencies = [ + "bitflags 2.5.0", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "gpu-allocator" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884" +dependencies = [ + "log", + "presser", + "thiserror", + "winapi", + "windows", +] + +[[package]] +name = "gpu-descriptor" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" +dependencies = [ + "bitflags 2.5.0", + "gpu-descriptor-types", + "hashbrown 0.14.5", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bf0b36e6f090b7e1d8a4b49c0cb81c1f8376f72198c65dd3ad9ff3556b8b78c" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "bytemuck", + "cfg-if", + "crunchy", + "num-traits", + "rand", + "rand_distr", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "hassle-rs" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" +dependencies = [ + "bitflags 2.5.0", + "com", + "libc", + "libloading 0.8.3", + "thiserror", + "widestring", + "winapi", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-traits", + "png", + "qoi", + "tiff", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", +] + +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" +dependencies = [ + "rayon", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading 0.8.3", + "pkg-config", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if", + "windows-targets 0.52.5", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.5.0", + "libc", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "lru" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "matrixmultiply" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +dependencies = [ + "autocfg", + "num_cpus", + "once_cell", + "rawpointer", + "thread-tree", +] + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memmap2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +dependencies = [ + "libc", + "stable_deref_trait", +] + +[[package]] +name = "metal" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" +dependencies = [ + "bitflags 2.5.0", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", + "paste", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "naga" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e3524642f53d9af419ab5e8dd29d3ba155708267667c2f3f06c88c9e130843" +dependencies = [ + "bit-set", + "bitflags 2.5.0", + "codespan-reporting", + "hexf-parse", + "indexmap", + "log", + "num-traits", + "rustc-hash", + "spirv", + "termcolor", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "ndarray" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "rawpointer", + "rayon", +] + +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "bytemuck", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "nvml-wrapper" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd21b9f5a1cce3c3515c9ffa85f5c7443e07162dae0ccf4339bb7ca38ad3454" +dependencies = [ + "bitflags 1.3.2", + "libloading 0.7.4", + "nvml-wrapper-sys", + "static_assertions", + "thiserror", + "wrapcenum-derive", +] + +[[package]] +name = "nvml-wrapper-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c961a2ea9e91c59a69b78e69090f6f5b867bb46c0c56de9482da232437c4987e" +dependencies = [ + "libloading 0.7.4", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking_lot" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.5", +] + +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest", + "hmac", + "password-hash", + "sha2", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "png" +version = "0.17.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "pollster" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + +[[package]] +name = "proc-macro2" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" + +[[package]] +name = "pulp" +version = "0.18.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "762ad20f6b65f5a33874de3b7506d6cf6631d37fb9c0c6ee0e310d7210a167d9" +dependencies = [ + "bytemuck", + "libm", + "num-complex", + "reborrow", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r2d2" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" +dependencies = [ + "log", + "parking_lot", + "scheduled-thread-pool", +] + +[[package]] +name = "r2d2_sqlite" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc290b669d30e20751e813517bbe13662d020419c5c8818ff10b6e8bb7777f6" +dependencies = [ + "r2d2", + "rusqlite", + "uuid", +] + +[[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 = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "range-alloc" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" + +[[package]] +name = "ratatui" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5659e52e4ba6e07b2dad9f1158f578ef84a73762625ddb51536019f34d180eb" +dependencies = [ + "bitflags 2.5.0", + "cassowary", + "crossterm", + "indoc", + "itertools", + "lru", + "paste", + "stability", + "strum", + "time", + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "raw-cpuid" +version = "10.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "reborrow" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430" + +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rmp" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + +[[package]] +name = "rusqlite" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a78046161564f5e7cd9008aff3b2990b3850dc8e0349119b98e8f251e099f24d" +dependencies = [ + "bitflags 2.5.0", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + +[[package]] +name = "rustls-webpki" +version = "0.102.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "safetensors" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93279b86b3de76f820a8854dd06cbc33cfa57a417b19c47f6a25280112fb1df" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "safetensors" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ced76b22c7fba1162f11a5a75d9d8405264b467a07ae0c9c29be119b9297db9" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "sanitize-filename" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ed72fbaf78e6f2d41744923916966c4fbe3d7c74e3037a8ee482f1115572603" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "scheduled-thread-pool" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "seq-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" + +[[package]] +name = "serde" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_rusqlite" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4600dac14aada464c5584d327baa164e372153309bc4c0fb1498bbfbaa5a028b" +dependencies = [ + "rusqlite", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spirv" +version = "0.3.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "stability" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd1b177894da2a2d9120208c3386066af06a488255caabc5de8ddca22dbc3ce" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.65", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "sysctl" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7dddc5f0fee506baf8b9fdb989e242f17e4b11c61dfbb0635b705217199eea" +dependencies = [ + "bitflags 2.5.0", + "byteorder", + "enum-as-inner", + "libc", + "thiserror", + "walkdir", +] + +[[package]] +name = "sysinfo" +version = "0.30.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732ffa00f53e6b2af46208fba5718d9662a421049204e156328b66791ffa15ae" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows", +] + +[[package]] +name = "systemstat" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a24aec24a9312c83999a28e3ef9db7e2afd5c64bf47725b758cdc1cafd5b0bd2" +dependencies = [ + "bytesize", + "lazy_static", + "libc", + "nom", + "time", + "winapi", +] + +[[package]] +name = "tank-rust" +version = "0.1.0" +dependencies = [ + "bincode 1.3.3", + "burn", + "cfg-if", + "lazy_static", + "rand", + "serde", +] + +[[package]] +name = "tch" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c7cb00bc2770454b515388d45be7097a3ded2eca172f3dcdb7ca4cc06c40bf1" +dependencies = [ + "half", + "lazy_static", + "libc", + "ndarray", + "rand", + "safetensors 0.3.3", + "thiserror", + "torch-sys", + "zip", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "text_placeholder" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512104f982ce6f50def5340f9d7d14cc21f7a859e9ccd251aa19d12e1345c070" +dependencies = [ + "hashbrown 0.13.2", + "serde", + "serde_json", +] + +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "thread-tree" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbd370cb847953a25954d9f63e14824a36113f8c72eecf6eccef5dc4b45d630" +dependencies = [ + "crossbeam-channel", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "torch-sys" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29e0244e5b148a31dd7fe961165037d1927754d024095c1013937532d7e73a22" +dependencies = [ + "anyhow", + "cc", + "libc", + "serde", + "serde_json", + "ureq", + "zip", +] + +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-width" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "ureq" +version = "2.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd" +dependencies = [ + "base64", + "flate2", + "log", + "once_cell", + "rustls", + "rustls-pki-types", + "rustls-webpki", + "serde", + "serde_json", + "url", + "webpki-roots", +] + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +dependencies = [ + "getrandom", + "rand", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.65", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + +[[package]] +name = "wgpu" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd7311dbd2abcfebaabf1841a2824ed7c8be443a0f29166e5d3c6a53a762c01" +dependencies = [ + "arrayvec", + "cfg-if", + "cfg_aliases", + "js-sys", + "log", + "naga", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b94525fc99ba9e5c9a9e24764f2bc29bad0911a7446c12f446a8277369bf3a" +dependencies = [ + "arrayvec", + "bit-vec", + "bitflags 2.5.0", + "cfg_aliases", + "codespan-reporting", + "indexmap", + "log", + "naga", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "rustc-hash", + "smallvec", + "thiserror", + "web-sys", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1a4924366df7ab41a5d8546d6534f1f33231aa5b3f72b9930e300f254e39c3" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set", + "bitflags 2.5.0", + "block", + "cfg_aliases", + "core-graphics-types", + "d3d12", + "glow", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "hassle-rs", + "js-sys", + "khronos-egl", + "libc", + "libloading 0.8.3", + "log", + "metal", + "naga", + "ndk-sys", + "objc", + "once_cell", + "parking_lot", + "profiling", + "range-alloc", + "raw-window-handle", + "renderdoc-sys", + "rustc-hash", + "smallvec", + "thiserror", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "winapi", +] + +[[package]] +name = "wgpu-types" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b671ff9fb03f78b46ff176494ee1ebe7d603393f42664be55b64dc8d53969805" +dependencies = [ + "bitflags 2.5.0", + "js-sys", + "web-sys", +] + +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + +[[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-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[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" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "wrapcenum-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76ff259533532054cfbaefb115c613203c73707017459206380f03b3b3f266e" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "xml-rs" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" + +[[package]] +name = "yoke" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e71b2e4f287f467794c671e2b8f8a5f3716b3c829079a1c44740148eff07e4" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e6936f0cce458098a201c245a11bef556c6a0181129c7034d10d76d1ec3a2b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "zerofrom" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "655b0814c5c0b19ade497851070c640773304939a6c0fd5f5fb43da0696d05b7" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "aes", + "byteorder", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "flate2", + "hmac", + "pbkdf2", + "sha1", + "time", + "zstd", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.10+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] diff --git a/tank-rust/Cargo.toml b/tank-rust/Cargo.toml new file mode 100644 index 0000000..9cc34db --- /dev/null +++ b/tank-rust/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "tank-rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[profile.release] +lto = true +opt-level = 's' +panic = "abort" +strip = "symbols" + +[lib] +crate_type = ["cdylib"] + +[dependencies] +burn = { version = "0.13.2", features = ["wgpu","dataset","train","tui","metrics","autodiff"] } +serde = {version="1.0.202", features = ["derive"]} +bincode = "1.3.3" +rand = "0.8.5" +lazy_static = "1.4.0" +cfg-if = "1.0.0" + +[features] +default = ["train"] +train = [] diff --git a/tank-rust/src/dqn/collect.rs b/tank-rust/src/dqn/collect.rs new file mode 100644 index 0000000..27a3455 --- /dev/null +++ b/tank-rust/src/dqn/collect.rs @@ -0,0 +1,90 @@ +use std::{ + fs::{File, OpenOptions}, + io::{BufWriter, Write}, +}; + +use super::dataset::TankItem; +use crate::{ffi::prelude::*, Backend}; +use burn::{backend::wgpu::WgpuDevice, module::Module, record::NoStdTrainingRecorder}; +use rand::{thread_rng, Rng}; + +use super::model::{DQNModel, DQNModelConfig}; +const EXPLORE_RATE: f32 = 0.4; + +pub struct App<'a> { + model: DQNModel, + device: WgpuDevice, + last_state_action: Option<(Info<'a>, Action)>, + #[cfg(feature = "train")] + outlet: BufWriter, +} + +impl<'a> App<'a> { + pub fn new(model_path: &str) -> Self { + let device = burn::backend::wgpu::WgpuDevice::default(); + + let model = DQNModelConfig::new().init(&device); + + let model = model + .load_file( + format!("{model_path}/model"), + &NoStdTrainingRecorder::new(), + &device, + ) + .unwrap(); + Self { + model, + device, + last_state_action: None, + #[cfg(feature = "train")] + outlet: BufWriter::new( + OpenOptions::new() + .write(true) + .create(true) + .open(format!("{model_path}/dataset")) + .unwrap(), + ), + } + } + #[cfg(feature = "train")] + pub fn flush(&mut self) { + self.outlet.flush().unwrap(); + } + #[cfg(feature = "train")] + pub fn collect_data(&mut self, state: &Info<'static>) -> Action { + if let Some((previous_state, action)) = self.last_state_action.take() { + let reward = previous_state.get_reward(state, action); + let item = TankItem { + previous_state: previous_state.into_feature(), + new_state: state.into_feature(), + action, + reward, + }; + bincode::serialize_into(&mut self.outlet, &item).unwrap(); + } + + let action = match thread_rng().gen_ratio((4096.0 * EXPLORE_RATE) as u32, 4096) { + true => match thread_rng().gen_range(0..15 as i32) { + 0 => Action::Forward, + 1 => Action::Backward, + 2 => Action::TurnRight, + 3 => Action::TurnLeft, + 4 => Action::AimRight, + 5 => Action::AimLeft, + 6 => Action::Shoot, + 7 => Action::TurnRight, + _ => Action::Forward, + }, + false => self.predict_action(state), + }; + + self.last_state_action = Some((state.clone(), action)); + + action + } + pub fn predict_action(&self, state: &Info) -> Action { + let input = state.into_feature_tensor(&self.device).unsqueeze(); // Convert input tensor to shape [1, input_size] + let ans = self.model.forward(input); + ans.argmax(1).into_scalar().try_into().unwrap() + } +} diff --git a/tank-rust/src/dqn/dataset.rs b/tank-rust/src/dqn/dataset.rs new file mode 100644 index 0000000..db61d2d --- /dev/null +++ b/tank-rust/src/dqn/dataset.rs @@ -0,0 +1,127 @@ +use std::{ + env::{self}, + fs::File, + io::BufReader, +}; + +use crate::ffi::prelude::*; +use crate::ARTIFACT_DIR; +use burn::{ + data::{dataloader::batcher::Batcher, dataset::Dataset}, + prelude::*, +}; + +use super::feature::FEATRUE_SPACE; + +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] +pub struct TankItem { + pub previous_state: [f32; FEATRUE_SPACE], + pub new_state: [f32; FEATRUE_SPACE], + pub action: Action, + pub reward: f32, +} + +pub struct TankDataset { + pub dataset: Vec, +} + +impl Dataset for TankDataset { + fn get(&self, index: usize) -> Option { + self.dataset.get(index).cloned() + } + + fn len(&self) -> usize { + self.dataset.len() + } +} + +impl TankDataset { + pub fn new() -> Self { + Self { + dataset: Vec::new(), + } + } + pub fn load() -> Self { + let dataset_path = env::var("MODEL_PATH").unwrap_or_else(|_| ARTIFACT_DIR.to_string()); + let mut dataset = Vec::new(); + println!("Loading dataset from: {}", dataset_path); + if let Ok(reader) = File::open(format!("{dataset_path}/dataset")) { + let mut reader = BufReader::new(reader); + while let Ok(item) = bincode::deserialize_from::<_, TankItem>(&mut reader) { + dataset.push(item); + } + } + TankDataset { dataset } + } + pub fn add(&mut self, item: TankItem) { + self.dataset.push(item); + } + pub fn split(self, ratio: f32) -> (Self, Self) { + let split = (self.dataset.len() as f32 * ratio).round() as usize; + let (a, b) = self.dataset.split_at(split); + ( + TankDataset { + dataset: a.to_vec(), + }, + TankDataset { + dataset: b.to_vec(), + }, + ) + } +} + +#[derive(Clone, Debug)] +pub struct TankBatcher { + device: B::Device, +} + +#[derive(Clone, Debug)] +pub struct TankBatch { + pub new_state: Tensor, + pub old_state: Tensor, + pub action: Tensor, + pub reward: Tensor, +} + +impl TankBatcher { + pub fn new(device: B::Device) -> Self { + Self { device } + } +} + +impl Batcher> for TankBatcher { + fn batch(&self, items: Vec) -> TankBatch { + let mut new_state: Vec> = Vec::new(); + let mut old_state: Vec> = Vec::new(); + + for item in items.iter() { + let new_state_tensor = Tensor::::from_floats(item.previous_state, &self.device); + let old_state_tensor = Tensor::::from_floats(item.new_state, &self.device); + + new_state.push(new_state_tensor.unsqueeze()); + old_state.push(old_state_tensor.unsqueeze()); + } + + let new_state = Tensor::cat(new_state, 0); + let old_state = Tensor::cat(old_state, 0); + + let reward = items + .iter() + .map(|item| Tensor::::from_floats([item.reward], &self.device)) + .collect(); + let reward = Tensor::cat(reward, 0); + + let response = items + .iter() + .map(|item| Tensor::::from_ints([item.action as i32], &self.device)) + .collect(); + let response = Tensor::cat(response, 0); + + TankBatch { + new_state, + old_state, + reward, + action: response, + } + } +} diff --git a/tank-rust/src/dqn/feature.rs b/tank-rust/src/dqn/feature.rs new file mode 100644 index 0000000..30dff81 --- /dev/null +++ b/tank-rust/src/dqn/feature.rs @@ -0,0 +1,192 @@ +//! Feature extraction and reward calculation for DQN +use std::f32::consts::PI; + +use burn::tensor::{backend::Backend, Tensor}; + +use crate::ffi::prelude::*; + +pub const FEATRUE_SPACE: usize = 10; +pub const ACTION_SPACE: usize = 7; + +#[derive(PartialEq, Default)] +struct Polar { + angle: f32, + distance: f32, +} + +impl Polar { + pub fn clip(&self) -> Self { + Polar { + angle: self.angle, + distance: self.distance.min(1e6).max(0.0), + } + } +} + +impl Eq for Polar {} + +impl Ord for Polar { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.distance.partial_cmp(&other.distance).unwrap() + } +} + +impl PartialOrd for Polar { + fn partial_cmp(&self, other: &Self) -> Option { + self.distance.partial_cmp(&other.distance) + } +} + +fn normalize_angle(mut angle: f32) -> f32 { + while angle < -PI { + angle += 2.0 * PI; + } + while angle >= PI { + angle -= 2.0 * PI; + } + angle +} + +impl Player { + fn to_pos(&self) -> (i32, i32) { + (self.x, self.y) + } + fn center(&self, x: i32, y: i32) -> Polar { + let dx = x - self.x; + let dy = y - self.y; + let angle = (dy as f32).atan2(dx as f32); + let distance = (dx.pow(2) + dy.pow(2)) as f32; + Polar { angle, distance } + } + fn closest(&self, others: impl Iterator) -> Polar { + others + .map(|(x, y)| self.center(x, y)) + .min() + .unwrap_or_default() + } + fn get_angle(&self) -> f32 { + (180 - self.angle) as f32 / 360.0 * 2.0 * PI + } + fn get_gun_angle(&self) -> f32 { + self.gun_angle as f32 / 360.0 * 2.0 * PI + } +} + +#[derive(Debug)] +enum Target { + Oil, + Bullet, + Enemy, +} + +impl Target { + fn get_pos(&self, info: &Info) -> Polar { + match self { + Target::Oil => info + .player + .closest(info.oil_stations.iter().map(Station::to_pos)), + Target::Bullet => info + .player + .closest(info.bullet_stations.iter().map(Station::to_pos)), + Target::Enemy => info.player.closest(info.enemies.iter().map(Player::to_pos)), + } + } + fn reach(&self, last: &Info, current: &Info) -> bool { + match self { + Target::Oil => last.player.oil > current.player.oil, + Target::Bullet => last.player.power > current.player.power, + Target::Enemy => false, + } + } +} + +impl Station { + fn to_pos(&self) -> (i32, i32) { + (self.x as i32, self.y as i32) + } +} + +impl Wall { + fn to_pos(&self) -> (i32, i32) { + (self.x, self.y) + } +} + +impl<'a> Info<'a> { + pub fn into_feature(&self) -> [f32; FEATRUE_SPACE] { + let emeny = self.player.closest(self.enemies.iter().map(Player::to_pos)); + let wall = self + .player + .closest(self.walls.iter().map(|wall| (wall.x, wall.y))); + let bullet = self + .player + .closest(self.bullets.iter().map(|bullet| (bullet.x, bullet.y))); + + let target = self.get_target().get_pos(self).clip(); + + let angle = self.player.get_angle(); + let gun_angle = self.player.get_gun_angle(); + + let feature = [ + normalize_angle(target.angle - angle).tanh(), + normalize_angle(target.angle - angle + PI).tanh(), + normalize_angle(bullet.angle - angle).tanh(), + (target.distance + 1.0).log2(), + (wall.distance - target.distance).tanh(), + (bullet.distance + 1.0).log2(), + normalize_angle(emeny.angle - gun_angle).tanh(), + normalize_angle(wall.angle - gun_angle).tanh(), + (self.player.oil - 40.0).tanh(), + (self.player.power as f32 - 7.0).tanh(), + ]; + + feature + } + pub fn into_feature_tensor(&self, device: &B::Device) -> Tensor { + let feature = self.into_feature(); + Tensor::from_floats(feature, device) + } + fn get_target(&self) -> Target { + if self.player.oil < 40.0 { + Target::Oil + } else if self.player.power > 7 { + Target::Enemy + } else { + Target::Bullet + } + } + pub fn get_reward(&self, next: &Self, action: Action) -> f32 { + let same_position = self.player.x == next.player.x && self.player.y == next.player.y; + let mut reward = -2.3; + reward += match action { + Action::Forward | Action::Backward if same_position => -8.0, + Action::Shoot => match next.player.power > 7 { + true => 2.0, + false => -2.0, + }, + _ => 0.0, + }; + + let target = self.get_target(); + + if target.reach(self, next) { + reward += 15.0; + } else { + let previous_target_position = target.get_pos(self); + let next_target_position = target.get_pos(next); + + reward += match previous_target_position.cmp(&next_target_position) { + std::cmp::Ordering::Less => -5.0, + std::cmp::Ordering::Equal => 0.0, + std::cmp::Ordering::Greater => 5.8, + }; + } + + reward + + match next.player.score - self.player.score { + x if x > 2 => 20.0, + x if x > 0 => 10.0, // too high, tank my ignore power station + _ => -1.0, + } + } +} diff --git a/tank-rust/src/dqn/mod.rs b/tank-rust/src/dqn/mod.rs new file mode 100644 index 0000000..3050f00 --- /dev/null +++ b/tank-rust/src/dqn/mod.rs @@ -0,0 +1,12 @@ +mod collect; +mod dataset; +mod feature; +mod model; +mod training; + +pub mod prelude { + pub use super::collect::App as DQNApp; + pub use super::dataset::{TankDataset, TankItem}; + pub use super::feature::{ACTION_SPACE, FEATRUE_SPACE}; + pub use super::training::run as train; +} diff --git a/tank-rust/src/dqn/model.rs b/tank-rust/src/dqn/model.rs new file mode 100644 index 0000000..8b0e46c --- /dev/null +++ b/tank-rust/src/dqn/model.rs @@ -0,0 +1,122 @@ +use super::{ + dataset::TankBatch, + feature::{ACTION_SPACE, FEATRUE_SPACE}, +}; +use burn::{ + nn::{ + loss::{HuberLoss, HuberLossConfig, Reduction::Mean}, + Linear, LinearConfig, Relu, + }, + prelude::*, + tensor::backend::AutodiffBackend, + train::{ + metric::{Adaptor, LossInput}, + TrainOutput, TrainStep, ValidStep, + }, +}; + +pub struct DQNOutput { + estimated_reward: Tensor, + expected_reward: Tensor, + loss: Tensor, +} + +impl Adaptor> for DQNOutput { + fn adapt(&self) -> LossInput { + LossInput::new(self.loss.clone()) + } +} + +#[derive(Module, Debug)] +pub struct DQNModel { + input_layer: Linear, + hidden_layer_1: Linear, + hidden_layer_2: Linear, + output_layer: Linear, + activation: Relu, + loss_function: HuberLoss, + gamma: f32, +} + +#[derive(Config)] +pub struct DQNModelConfig { + #[config(default = 64)] + pub hidden_layer_1_size: usize, + #[config(default = 96)] + pub hidden_layer_2_size: usize, + #[config(default = 64)] + pub hidden_layer_3_size: usize, + #[config(default = 0.99)] + pub gamma: f32, +} + +impl DQNModelConfig { + pub fn init(&self, device: &B::Device) -> DQNModel { + let input_layer = LinearConfig::new(FEATRUE_SPACE, self.hidden_layer_1_size) + .with_bias(true) + .init(device); + let hidden_layer_1 = LinearConfig::new(self.hidden_layer_1_size, self.hidden_layer_2_size) + .with_bias(true) + .init(device); + let hidden_layer_2 = LinearConfig::new(self.hidden_layer_2_size, self.hidden_layer_3_size) + .with_bias(true) + .init(device); + let output_layer = LinearConfig::new(self.hidden_layer_3_size, ACTION_SPACE) + .with_bias(true) + .init(device); + + DQNModel { + input_layer, + hidden_layer_1, + hidden_layer_2, + output_layer, + loss_function: HuberLossConfig::new(1.34).init(device), + activation: Relu::new(), + gamma: self.gamma, + } + } +} + +impl DQNModel { + pub fn forward(&self, input: Tensor) -> Tensor { + let x = input.detach(); + let x = self.input_layer.forward(x); + let x = self.activation.forward(x); + self.output_layer.forward(x) + } + + pub fn forward_step(&self, item: TankBatch) -> DQNOutput { + let estimated_reward = self.forward(item.new_state); + + // FIXME: magic unsqueeze + let a = item.action.unsqueeze_dim(1); + let x = estimated_reward.clone().gather(1, a); + + // FIXME: what's final mask + let expected_reward = self.forward(item.old_state); + let y = expected_reward.clone().max_dim(1); + let y = y.mul_scalar(self.gamma).add(item.reward.unsqueeze()); + + let loss = self.loss_function.forward(x, y, Mean); + + DQNOutput { + estimated_reward, + expected_reward, + loss, + } + } +} + +impl TrainStep, DQNOutput> for DQNModel { + fn step(&self, item: TankBatch) -> TrainOutput> { + let item = self.forward_step(item); + + TrainOutput::new(self, item.loss.backward(), item) + } +} + +impl ValidStep, DQNOutput> for DQNModel { + fn step(&self, item: TankBatch) -> DQNOutput { + self.forward_step(item) + } +} diff --git a/tank-rust/src/dqn/training.rs b/tank-rust/src/dqn/training.rs new file mode 100644 index 0000000..906b07c --- /dev/null +++ b/tank-rust/src/dqn/training.rs @@ -0,0 +1,103 @@ +use std::{env, fs}; + +use super::dataset::{TankBatcher, TankDataset}; +use super::model::DQNModelConfig; +use crate::ARTIFACT_DIR; +use burn::optim::AdamConfig; +use burn::train::metric::store::{Aggregate, Direction, Split}; +use burn::train::{MetricEarlyStoppingStrategy, StoppingCondition}; +use burn::{ + data::{dataloader::DataLoaderBuilder, dataset::Dataset}, + prelude::*, + record::{CompactRecorder, NoStdTrainingRecorder}, + tensor::backend::AutodiffBackend, + train::{metric::LossMetric, LearnerBuilder}, +}; +#[derive(Config)] +pub struct ExpConfig { + #[config(default = 16)] + pub num_epochs: usize, + + #[config(default = 6)] + pub num_workers: usize, + + #[config(default = 47)] + pub seed: u64, + + pub optimizer: AdamConfig, + + #[config(default = 1.5e-3)] + pub learn_rate: f64, + + #[config(default = 4096)] + pub batch_size: usize, +} + +pub fn run(device: B::Device) +where + B: AutodiffBackend, +{ + let model_path = env::var("MODEL_PATH").unwrap_or_else(|_| ARTIFACT_DIR.to_string()); + + let optimizer = AdamConfig::new(); + let config = ExpConfig::new(optimizer); + let mut model = DQNModelConfig::new().init(&device); + + if fs::metadata(format!("{model_path}/model")).is_ok() { + model = model + .load_file( + format!("{model_path}/model"), + &NoStdTrainingRecorder::new(), + &device, + ) + .unwrap(); + } + + B::seed(config.seed); + + let (train_dataset, test_dataset) = TankDataset::load().split(1.0); + + println!("Train Dataset Size: {}", train_dataset.len()); + println!("Test Dataset Size: {}", test_dataset.len()); + + let batcher_train = TankBatcher::::new(device.clone()); + + let batcher_test = TankBatcher::::new(device.clone()); + + let dataloader_train = DataLoaderBuilder::new(batcher_train) + .batch_size(config.batch_size) + .shuffle(config.seed) + .num_workers(config.num_workers) + .build(train_dataset); + + let dataloader_test = DataLoaderBuilder::new(batcher_test) + .batch_size(config.batch_size) + .shuffle(config.seed) + .num_workers(config.num_workers) + .build(test_dataset); + + let learner = LearnerBuilder::new(&model_path) + .metric_train_numeric(LossMetric::new()) + .metric_valid_numeric(LossMetric::new()) + .with_file_checkpointer(CompactRecorder::new()) + .early_stopping(MetricEarlyStoppingStrategy::new::>( + Aggregate::Mean, + Direction::Lowest, + Split::Train, + StoppingCondition::NoImprovementSince { n_epochs: 2 }, + )) + .devices(vec![device.clone()]) + .num_epochs(config.num_epochs) + .summary() + .build(model, config.optimizer.init(), config.learn_rate); + + let model_trained = learner.fit(dataloader_train, dataloader_test); + + config + .save(format!("{model_path}/config.json").as_str()) + .unwrap(); + + model_trained + .save_file(format!("{model_path}/model"), &NoStdTrainingRecorder::new()) + .expect("Failed to save trained model"); +} diff --git a/tank-rust/src/ffi/action.rs b/tank-rust/src/ffi/action.rs new file mode 100644 index 0000000..045d331 --- /dev/null +++ b/tank-rust/src/ffi/action.rs @@ -0,0 +1,30 @@ +#[repr(i32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize)] +pub enum Action { + Forward = 0, + Backward = 1, + TurnRight = 2, + TurnLeft = 3, + AimRight = 4, + AimLeft = 5, + Shoot = 6, + None = 7, +} + +impl TryFrom for Action { + type Error = &'static str; + + fn try_from(value: i32) -> Result { + match value { + 0 => Ok(Action::Forward), + 1 => Ok(Action::Backward), + 2 => Ok(Action::TurnRight), + 3 => Ok(Action::TurnLeft), + 4 => Ok(Action::AimRight), + 5 => Ok(Action::AimLeft), + 6 => Ok(Action::Shoot), + 7 => Ok(Action::None), + _ => Err("Invalid action"), + } + } +} diff --git a/tank-rust/src/ffi/info/bullet.rs b/tank-rust/src/ffi/info/bullet.rs new file mode 100644 index 0000000..8917022 --- /dev/null +++ b/tank-rust/src/ffi/info/bullet.rs @@ -0,0 +1,6 @@ +#[repr(C)] +#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize)] +pub struct Bullet { + pub x: i32, + pub y: i32, +} diff --git a/tank-rust/src/ffi/info/mod.rs b/tank-rust/src/ffi/info/mod.rs new file mode 100644 index 0000000..10259a1 --- /dev/null +++ b/tank-rust/src/ffi/info/mod.rs @@ -0,0 +1,58 @@ +mod bullet; +mod player; +mod station; +mod wall; + +pub use bullet::*; +pub use player::*; +pub use station::*; +pub use wall::*; + +#[derive(Debug, Clone, Default)] +pub struct Info<'a> { + pub player: Player, + pub teammates: &'a [Player], + pub enemies: &'a [Player], + pub bullets: &'a [Bullet], + pub bullet_stations: &'a [Station], + pub oil_stations: &'a [Station], + pub walls: &'a [Wall], +} + +#[repr(C)] +pub struct RawInfo { + player: *const Player, + teammates: *const Player, + teammates_len: u32, + enemies: *const Player, + enemies_len: u32, + bullets: *const Bullet, + bullet_len: u32, + bullet_stations: *const Station, + bullet_stations_len: u32, + oil_stations: *const Station, + oil_stations_len: u32, + walls: *const Wall, + walls_len: u32, +} + +impl<'a> Info<'a> { + pub unsafe fn from_raw(self_: *const RawInfo) -> Self { + let raw = &*self_; + Info { + player: (&*raw.player).clone(), + teammates: std::slice::from_raw_parts(raw.teammates, raw.teammates_len as usize), + enemies: std::slice::from_raw_parts(raw.enemies, raw.enemies_len as usize), + bullets: std::slice::from_raw_parts(raw.bullets, raw.bullet_len as usize), + bullet_stations: std::slice::from_raw_parts( + raw.bullet_stations, + raw.bullet_stations_len as usize, + ), + oil_stations: std::slice::from_raw_parts( + raw.oil_stations, + raw.oil_stations_len as usize, + ), + walls: std::slice::from_raw_parts(raw.walls, raw.walls_len as usize), + } + } +} diff --git a/tank-rust/src/ffi/info/player.rs b/tank-rust/src/ffi/info/player.rs new file mode 100644 index 0000000..d0c49e6 --- /dev/null +++ b/tank-rust/src/ffi/info/player.rs @@ -0,0 +1,14 @@ +#[repr(C)] +#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, Default)] +pub struct Player { + pub x: i32, + pub y: i32, + pub speed: i32, + pub score: i32, + pub power: i32, + pub oil: f32, + pub lives: i32, + pub angle: i32, + pub gun_angle: i32, + pub cooldown: i32, +} diff --git a/tank-rust/src/ffi/info/station.rs b/tank-rust/src/ffi/info/station.rs new file mode 100644 index 0000000..6abe3f6 --- /dev/null +++ b/tank-rust/src/ffi/info/station.rs @@ -0,0 +1,7 @@ +#[repr(C)] +#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize, Default)] +pub struct Station { + pub x: i32, + pub y: i32, + pub power: i32, +} diff --git a/tank-rust/src/ffi/info/wall.rs b/tank-rust/src/ffi/info/wall.rs new file mode 100644 index 0000000..d8c0931 --- /dev/null +++ b/tank-rust/src/ffi/info/wall.rs @@ -0,0 +1,7 @@ +#[repr(C)] +#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize)] +pub struct Wall { + pub x: i32, + pub y: i32, + pub lives: i32, +} diff --git a/tank-rust/src/ffi/mod.rs b/tank-rust/src/ffi/mod.rs new file mode 100644 index 0000000..25a52af --- /dev/null +++ b/tank-rust/src/ffi/mod.rs @@ -0,0 +1,7 @@ +mod action; +mod info; + +pub mod prelude { + pub use super::action::*; + pub use super::info::*; +} diff --git a/tank-rust/src/fit.rs b/tank-rust/src/fit.rs new file mode 100644 index 0000000..404c6da --- /dev/null +++ b/tank-rust/src/fit.rs @@ -0,0 +1,77 @@ +use burn::data::dataset::Dataset; + +use crate::dqn::prelude::TankItem; +use crate::ffi::prelude::*; +use rand::Rng; + +// fn random_action() -> Action { +// let mut rng = rand::thread_rng(); +// match rng.gen_range(0..2) { +// 0 => Action::AimLeft, +// 1 => Action::Forward, +// _ => unreachable!(), +// } +// } + +// fn random_item() -> TankItem { +// let mut previous_info=Info::default(); +// TankItem { +// previous_state: todo!(), +// new_state: todo!(), +// action: todo!(), +// reward: todo!(), +// } +// } + +pub struct FitDataset; + +impl FitDataset { + /// Get closer to the power station + fn close_power_station() -> TankItem { + let mut power_stations = Station::default(); + + let mut previous_info = Info::default(); + let mut new_info = Info::default(); + let mut rng = rand::thread_rng(); + previous_info.player.power = rng.gen_range(0..2); + new_info.player.power = previous_info.player.power; + previous_info.player.angle = rng.gen_range(0..360); + new_info.player.angle = previous_info.player.angle; + + TankItem { + previous_state: todo!(), + new_state: todo!(), + action: Action::Forward, + reward: todo!(), + } + } + /// Flee from power station if power is high + fn flee_power_station() -> TankItem { + let mut previous_info = Info::default(); + TankItem { + previous_state: todo!(), + new_state: todo!(), + action: Action::Backward, + reward: todo!(), + } + } +} + +impl Dataset for FitDataset { + fn get(&self, _: usize) -> Option { + let previous_state = todo!(); + let new_state = todo!(); + let action = Action::AimLeft; + let reward = 0.0; + Some(TankItem { + previous_state, + new_state, + action, + reward, + }) + } + + fn len(&self) -> usize { + 1 + } +} diff --git a/tank-rust/src/lib.rs b/tank-rust/src/lib.rs new file mode 100644 index 0000000..4fe8d71 --- /dev/null +++ b/tank-rust/src/lib.rs @@ -0,0 +1,44 @@ +mod dqn; +mod ffi; +use std::{ffi::OsStr, os::unix::ffi::OsStrExt}; + +use burn::backend::{wgpu::AutoGraphicsApi, Wgpu}; +use dqn::prelude::*; +use ffi::prelude::*; + +static ARTIFACT_DIR: &str = "../output"; + +type Backend = Wgpu; + +#[no_mangle] +pub extern "C" fn init(model_path: *const u8, len: i32) -> *mut DQNApp<'static> { + let model_path = + OsStr::from_bytes(unsafe { std::slice::from_raw_parts(model_path, len as usize) }) + .to_str() + .unwrap(); + let app = DQNApp::new(model_path); + + Box::into_raw(Box::new(app)) +} + +#[no_mangle] +pub extern "C" fn tick(app: *mut DQNApp, raw: *mut RawInfo) -> i32 { + let app = unsafe { &mut *app }; + let info: Info<'static> = unsafe { Info::from_raw(raw) }; + cfg_if::cfg_if! { + if #[cfg(feature = "train")]{ + app.collect_data(&info)as i32 + }else{ + app.predict_action(&info)as i32 + } + } +} + +#[no_mangle] +pub extern "C" fn flush(app: *mut DQNApp) { + let app = unsafe { &mut *app }; + #[cfg(feature = "train")] + { + app.flush(); + } +} diff --git a/tank-rust/src/main.rs b/tank-rust/src/main.rs new file mode 100644 index 0000000..592bd8f --- /dev/null +++ b/tank-rust/src/main.rs @@ -0,0 +1,14 @@ +mod dqn; +mod ffi; +use burn::backend::{wgpu::AutoGraphicsApi, Autodiff, Wgpu}; + +static ARTIFACT_DIR: &str = "../output"; + +type Backend = Wgpu; +type AutodiffBackend = Autodiff; + +pub fn main() { + let device = burn::backend::wgpu::WgpuDevice::default(); + + dqn::prelude::train::(device); +} diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..7a0a0f7 --- /dev/null +++ b/test.sh @@ -0,0 +1,11 @@ +#!/bin/bash +export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6 +if [ "$XDG_SESSION_TYPE" == "x11" ]; then + export DISPLAY=:0.0 +fi +cd TankMan +python -m mlgame -f 400 \ +-i ../ml/collect1.py -i ../ml/test.py \ +. --green_team_num 1 --blue_team_num 1 --is_manual 1 \ +--frame_limit 1000 > /dev/null +cd .. diff --git a/train.sh b/train.sh new file mode 100755 index 0000000..9d75305 --- /dev/null +++ b/train.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6 +if [ "$XDG_SESSION_TYPE" == "x11" ]; then + export DISPLAY=:0.0 +fi + +for i in $(seq 1 $1); +do + echo "epoch $i" + cd TankMan + timeout 240 python -m mlgame -f 3000 \ + -i ../ml/collect1.py -i ../ml/collect2.py \ + . --green_team_num 1 --blue_team_num 1 --is_manual 1 \ + --frame_limit 1000 > /dev/null + cd .. + + MODEL_PATH="output1" ./train + MODEL_PATH="output2" ./train + + rm output1/dataset + rm output2/dataset +done