This commit is contained in:
		
							
								
								
									
										308
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										308
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -26,6 +26,12 @@ dependencies = [ | ||||
|  "memchr", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "anes" | ||||
| version = "0.1.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" | ||||
|  | ||||
| [[package]] | ||||
| name = "anstream" | ||||
| version = "0.6.18" | ||||
| @@ -173,6 +179,7 @@ version = "2.0.0" | ||||
| dependencies = [ | ||||
|  "axum", | ||||
|  "bitvec", | ||||
|  "criterion", | ||||
|  "enum-iterator", | ||||
|  "env_logger", | ||||
|  "log", | ||||
| @@ -202,6 +209,12 @@ dependencies = [ | ||||
|  "generic-array", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "bumpalo" | ||||
| version = "3.16.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" | ||||
|  | ||||
| [[package]] | ||||
| name = "byteorder" | ||||
| version = "1.5.0" | ||||
| @@ -214,12 +227,70 @@ version = "1.9.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" | ||||
|  | ||||
| [[package]] | ||||
| name = "cast" | ||||
| version = "0.3.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" | ||||
|  | ||||
| [[package]] | ||||
| name = "cfg-if" | ||||
| version = "1.0.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" | ||||
|  | ||||
| [[package]] | ||||
| name = "ciborium" | ||||
| version = "0.2.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" | ||||
| dependencies = [ | ||||
|  "ciborium-io", | ||||
|  "ciborium-ll", | ||||
|  "serde", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "ciborium-io" | ||||
| version = "0.2.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" | ||||
|  | ||||
| [[package]] | ||||
| name = "ciborium-ll" | ||||
| version = "0.2.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" | ||||
| dependencies = [ | ||||
|  "ciborium-io", | ||||
|  "half", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "clap" | ||||
| version = "4.5.27" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796" | ||||
| dependencies = [ | ||||
|  "clap_builder", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "clap_builder" | ||||
| version = "4.5.27" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" | ||||
| dependencies = [ | ||||
|  "anstyle", | ||||
|  "clap_lex", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "clap_lex" | ||||
| version = "0.7.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" | ||||
|  | ||||
| [[package]] | ||||
| name = "colorchoice" | ||||
| version = "1.0.3" | ||||
| @@ -235,6 +306,42 @@ dependencies = [ | ||||
|  "libc", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "criterion" | ||||
| version = "0.5.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" | ||||
| dependencies = [ | ||||
|  "anes", | ||||
|  "cast", | ||||
|  "ciborium", | ||||
|  "clap", | ||||
|  "criterion-plot", | ||||
|  "is-terminal", | ||||
|  "itertools", | ||||
|  "num-traits", | ||||
|  "once_cell", | ||||
|  "oorandom", | ||||
|  "plotters", | ||||
|  "rayon", | ||||
|  "regex", | ||||
|  "serde", | ||||
|  "serde_derive", | ||||
|  "serde_json", | ||||
|  "tinytemplate", | ||||
|  "walkdir", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "criterion-plot" | ||||
| version = "0.5.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" | ||||
| dependencies = [ | ||||
|  "cast", | ||||
|  "itertools", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "crossbeam-deque" | ||||
| version = "0.8.6" | ||||
| @@ -260,6 +367,12 @@ version = "0.8.21" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" | ||||
|  | ||||
| [[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" | ||||
| @@ -458,12 +571,28 @@ dependencies = [ | ||||
|  "tracing", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "half" | ||||
| version = "2.4.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" | ||||
| dependencies = [ | ||||
|  "cfg-if", | ||||
|  "crunchy", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "hashbrown" | ||||
| version = "0.15.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" | ||||
|  | ||||
| [[package]] | ||||
| name = "hermit-abi" | ||||
| version = "0.4.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" | ||||
|  | ||||
| [[package]] | ||||
| name = "http" | ||||
| version = "1.2.0" | ||||
| @@ -562,18 +691,48 @@ dependencies = [ | ||||
|  "hashbrown", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "is-terminal" | ||||
| version = "0.4.13" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" | ||||
| dependencies = [ | ||||
|  "hermit-abi", | ||||
|  "libc", | ||||
|  "windows-sys 0.52.0", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "is_terminal_polyfill" | ||||
| version = "1.70.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" | ||||
|  | ||||
| [[package]] | ||||
| name = "itertools" | ||||
| version = "0.10.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" | ||||
| dependencies = [ | ||||
|  "either", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "itoa" | ||||
| version = "1.0.14" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" | ||||
|  | ||||
| [[package]] | ||||
| name = "js-sys" | ||||
| version = "0.3.77" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" | ||||
| dependencies = [ | ||||
|  "once_cell", | ||||
|  "wasm-bindgen", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "libc" | ||||
| version = "0.2.169" | ||||
| @@ -641,6 +800,15 @@ dependencies = [ | ||||
|  "version_check", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "num-traits" | ||||
| version = "0.2.19" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" | ||||
| dependencies = [ | ||||
|  "autocfg", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "object" | ||||
| version = "0.36.7" | ||||
| @@ -656,6 +824,12 @@ version = "1.20.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" | ||||
|  | ||||
| [[package]] | ||||
| name = "oorandom" | ||||
| version = "11.1.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" | ||||
|  | ||||
| [[package]] | ||||
| name = "percent-encoding" | ||||
| version = "2.3.1" | ||||
| @@ -674,6 +848,34 @@ version = "0.1.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" | ||||
|  | ||||
| [[package]] | ||||
| name = "plotters" | ||||
| version = "0.3.7" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" | ||||
| dependencies = [ | ||||
|  "num-traits", | ||||
|  "plotters-backend", | ||||
|  "plotters-svg", | ||||
|  "wasm-bindgen", | ||||
|  "web-sys", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "plotters-backend" | ||||
| version = "0.3.7" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" | ||||
|  | ||||
| [[package]] | ||||
| name = "plotters-svg" | ||||
| version = "0.3.7" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" | ||||
| dependencies = [ | ||||
|  "plotters-backend", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "ppv-lite86" | ||||
| version = "0.2.20" | ||||
| @@ -804,6 +1006,15 @@ version = "1.0.18" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" | ||||
|  | ||||
| [[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 = "serde" | ||||
| version = "1.0.217" | ||||
| @@ -943,6 +1154,16 @@ dependencies = [ | ||||
|  "syn", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tinytemplate" | ||||
| version = "1.2.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" | ||||
| dependencies = [ | ||||
|  "serde", | ||||
|  "serde_json", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tokio" | ||||
| version = "1.43.0" | ||||
| @@ -1091,12 +1312,99 @@ version = "0.9.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" | ||||
|  | ||||
| [[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.100" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" | ||||
| dependencies = [ | ||||
|  "cfg-if", | ||||
|  "once_cell", | ||||
|  "rustversion", | ||||
|  "wasm-bindgen-macro", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "wasm-bindgen-backend" | ||||
| version = "0.2.100" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" | ||||
| dependencies = [ | ||||
|  "bumpalo", | ||||
|  "log", | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "wasm-bindgen-shared", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "wasm-bindgen-macro" | ||||
| version = "0.2.100" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" | ||||
| dependencies = [ | ||||
|  "quote", | ||||
|  "wasm-bindgen-macro-support", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "wasm-bindgen-macro-support" | ||||
| version = "0.2.100" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
|  "wasm-bindgen-backend", | ||||
|  "wasm-bindgen-shared", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "wasm-bindgen-shared" | ||||
| version = "0.2.100" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" | ||||
| dependencies = [ | ||||
|  "unicode-ident", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "web-sys" | ||||
| version = "0.3.77" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" | ||||
| dependencies = [ | ||||
|  "js-sys", | ||||
|  "wasm-bindgen", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "winapi-util" | ||||
| version = "0.1.9" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" | ||||
| dependencies = [ | ||||
|  "windows-sys 0.59.0", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "windows-sys" | ||||
| version = "0.52.0" | ||||
|   | ||||
| @@ -29,3 +29,10 @@ env_logger = "0.11" | ||||
| bitvec = "1.0" | ||||
| enum-iterator = "2.1" | ||||
| rand = "0.8" | ||||
|  | ||||
| [dev-dependencies] | ||||
| criterion = "0.5" | ||||
|  | ||||
| [[bench]] | ||||
| name = "simulation" | ||||
| harness = false | ||||
|   | ||||
							
								
								
									
										220
									
								
								battlesnake/benches/simulation.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								battlesnake/benches/simulation.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,220 @@ | ||||
| use std::sync::atomic::{AtomicU32, Ordering}; | ||||
|  | ||||
| use criterion::{black_box, criterion_group, criterion_main, Bencher, BenchmarkId, Criterion}; | ||||
|  | ||||
| use battlesnake::types::{ | ||||
|     simulation::Board, | ||||
|     wire::{Battlesnake, Board as WireBoard, Game, Request, RoyaleSettings, Ruleset, Settings}, | ||||
|     Coord, | ||||
| }; | ||||
|  | ||||
| fn create_start_snake(coord: Coord) -> Battlesnake { | ||||
|     let id = format!("{coord:?}"); | ||||
|     Battlesnake { | ||||
|         id: id.clone(), | ||||
|         name: id.clone(), | ||||
|         health: 100, | ||||
|         body: vec![coord; 3], | ||||
|         latency: "0".into(), | ||||
|         head: coord, | ||||
|         length: 3, | ||||
|         shout: String::new(), | ||||
|         squad: id, | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn create_standard_start_request(starts: [Coord; 4]) -> Request { | ||||
|     Request { | ||||
|         game: Game { | ||||
|             id: "test".into(), | ||||
|             ruleset: Ruleset { | ||||
|                 name: "standard".into(), | ||||
|                 version: "0".into(), | ||||
|                 settings: Settings { | ||||
|                     food_spawn_chance: 15, | ||||
|                     minimum_food: 1, | ||||
|                     hazard_damage_per_turn: 30, | ||||
|                     royale: RoyaleSettings { | ||||
|                         shrink_every_n_turns: 20, | ||||
|                     }, | ||||
|                 }, | ||||
|             }, | ||||
|             map: "standard".into(), | ||||
|             timeout: 500, | ||||
|             source: "other".into(), | ||||
|         }, | ||||
|         turn: 0, | ||||
|         board: WireBoard { | ||||
|             height: 11, | ||||
|             width: 11, | ||||
|             food: vec![Coord { x: 5, y: 5 }], | ||||
|             hazards: vec![], | ||||
|             snakes: vec![ | ||||
|                 create_start_snake(starts[0]), | ||||
|                 create_start_snake(starts[1]), | ||||
|                 create_start_snake(starts[2]), | ||||
|                 create_start_snake(starts[3]), | ||||
|             ], | ||||
|         }, | ||||
|         you: create_start_snake(starts[0]), | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn standard(c: &mut Criterion) { | ||||
|     let turns_min = AtomicU32::new(u32::MAX); | ||||
|     let turns_max = AtomicU32::new(u32::MIN); | ||||
|     let turns_sum = AtomicU32::new(0); | ||||
|     let turns_total = AtomicU32::new(0); | ||||
|     let mut group = c.benchmark_group("standard"); | ||||
|     group.sample_size(10000); | ||||
|  | ||||
|     let benchmark = |b: &mut Bencher, board: &Board| { | ||||
|         b.iter(|| { | ||||
|             let mut board = board.clone(); | ||||
|             let turn = board.simulate_random(|board| { | ||||
|                 if board.num_snakes() <= 1 { | ||||
|                     Some(board.turn()) | ||||
|                 } else { | ||||
|                     None | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             if turn < turns_min.load(Ordering::Relaxed) { | ||||
|                 turns_min.store(turn, Ordering::Relaxed); | ||||
|             } | ||||
|             if turn > turns_max.load(Ordering::Relaxed) { | ||||
|                 turns_max.store(turn, Ordering::Relaxed); | ||||
|             } | ||||
|             turns_sum.fetch_add(turn, Ordering::Relaxed); | ||||
|             turns_total.fetch_add(1, Ordering::Relaxed); | ||||
|         }); | ||||
|     }; | ||||
|  | ||||
|     let request = create_standard_start_request([ | ||||
|         Coord { x: 1, y: 1 }, | ||||
|         Coord { x: 9, y: 1 }, | ||||
|         Coord { x: 1, y: 9 }, | ||||
|         Coord { x: 9, y: 9 }, | ||||
|     ]); | ||||
|     let board = Board::from(&request); | ||||
|     group.bench_with_input( | ||||
|         BenchmarkId::from_parameter("start x"), | ||||
|         black_box(&board), | ||||
|         benchmark, | ||||
|     ); | ||||
|     { | ||||
|         let max = turns_max.load(Ordering::Relaxed); | ||||
|         let min = turns_min.load(Ordering::Relaxed); | ||||
|         let sum = turns_sum.load(Ordering::Relaxed); | ||||
|         let total = turns_total.load(Ordering::Relaxed); | ||||
|         let avg = sum / total; | ||||
|         println!("turns: [{min}, {max}] avg {avg} @ {total} samples"); | ||||
|         turns_max.store(u32::MIN, Ordering::Relaxed); | ||||
|         turns_min.store(u32::MAX, Ordering::Relaxed); | ||||
|         turns_sum.store(0, Ordering::Relaxed); | ||||
|         turns_total.store(0, Ordering::Relaxed); | ||||
|     } | ||||
|  | ||||
|     let request = create_standard_start_request([ | ||||
|         Coord { x: 5, y: 1 }, | ||||
|         Coord { x: 1, y: 5 }, | ||||
|         Coord { x: 5, y: 9 }, | ||||
|         Coord { x: 9, y: 5 }, | ||||
|     ]); | ||||
|     let board = Board::from(&request); | ||||
|     group.bench_with_input( | ||||
|         BenchmarkId::from_parameter("start +"), | ||||
|         black_box(&board), | ||||
|         benchmark, | ||||
|     ); | ||||
|     { | ||||
|         let max = turns_max.load(Ordering::Relaxed); | ||||
|         let min = turns_min.load(Ordering::Relaxed); | ||||
|         let sum = turns_sum.load(Ordering::Relaxed); | ||||
|         let total = turns_total.load(Ordering::Relaxed); | ||||
|         let avg = sum / total; | ||||
|         println!("turns: [{min}, {max}] avg {avg} @ {total} samples"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn constrictor(c: &mut Criterion) { | ||||
|     let turns_min = AtomicU32::new(u32::MAX); | ||||
|     let turns_max = AtomicU32::new(u32::MIN); | ||||
|     let turns_sum = AtomicU32::new(0); | ||||
|     let turns_total = AtomicU32::new(0); | ||||
|     let mut group = c.benchmark_group("constrictor"); | ||||
|     group.sample_size(10000); | ||||
|  | ||||
|     let benchmark = |b: &mut Bencher, board: &Board| { | ||||
|         b.iter(|| { | ||||
|             let mut board = board.clone(); | ||||
|             let turn = board.simulate_random(|board| { | ||||
|                 if board.num_snakes() <= 1 { | ||||
|                     Some(board.turn()) | ||||
|                 } else { | ||||
|                     None | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             if turn < turns_min.load(Ordering::Relaxed) { | ||||
|                 turns_min.store(turn, Ordering::Relaxed); | ||||
|             } | ||||
|             if turn > turns_max.load(Ordering::Relaxed) { | ||||
|                 turns_max.store(turn, Ordering::Relaxed); | ||||
|             } | ||||
|             turns_sum.fetch_add(turn, Ordering::Relaxed); | ||||
|             turns_total.fetch_add(1, Ordering::Relaxed); | ||||
|         }); | ||||
|     }; | ||||
|  | ||||
|     let mut request = create_standard_start_request([ | ||||
|         Coord { x: 1, y: 1 }, | ||||
|         Coord { x: 9, y: 1 }, | ||||
|         Coord { x: 1, y: 9 }, | ||||
|         Coord { x: 9, y: 9 }, | ||||
|     ]); | ||||
|     request.game.ruleset.name = "constrictor".into(); | ||||
|     let board = Board::from(&request); | ||||
|     group.bench_with_input( | ||||
|         BenchmarkId::from_parameter("start x"), | ||||
|         black_box(&board), | ||||
|         benchmark, | ||||
|     ); | ||||
|     { | ||||
|         let max = turns_max.load(Ordering::Relaxed); | ||||
|         let min = turns_min.load(Ordering::Relaxed); | ||||
|         let sum = turns_sum.load(Ordering::Relaxed); | ||||
|         let total = turns_total.load(Ordering::Relaxed); | ||||
|         let avg = sum / total; | ||||
|         println!("turns: [{min}, {max}] avg {avg} @ {total} samples"); | ||||
|         turns_max.store(u32::MIN, Ordering::Relaxed); | ||||
|         turns_min.store(u32::MAX, Ordering::Relaxed); | ||||
|         turns_sum.store(0, Ordering::Relaxed); | ||||
|         turns_total.store(0, Ordering::Relaxed); | ||||
|     } | ||||
|  | ||||
|     let mut request = create_standard_start_request([ | ||||
|         Coord { x: 5, y: 1 }, | ||||
|         Coord { x: 1, y: 5 }, | ||||
|         Coord { x: 5, y: 9 }, | ||||
|         Coord { x: 9, y: 5 }, | ||||
|     ]); | ||||
|     request.game.ruleset.name = "constrictor".into(); | ||||
|     let board = Board::from(&request); | ||||
|     group.bench_with_input( | ||||
|         BenchmarkId::from_parameter("start +"), | ||||
|         black_box(&board), | ||||
|         benchmark, | ||||
|     ); | ||||
|     { | ||||
|         let max = turns_max.load(Ordering::Relaxed); | ||||
|         let min = turns_min.load(Ordering::Relaxed); | ||||
|         let sum = turns_sum.load(Ordering::Relaxed); | ||||
|         let total = turns_total.load(Ordering::Relaxed); | ||||
|         let avg = sum / total; | ||||
|         println!("turns: [{min}, {max}] avg {avg} @ {total} samples"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| criterion_group!(benches, standard, constrictor); | ||||
| criterion_main!(benches); | ||||
							
								
								
									
										1
									
								
								battlesnake/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								battlesnake/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| pub mod types; | ||||
| @@ -1,20 +1,18 @@ | ||||
| mod types; | ||||
|  | ||||
| use axum::{ | ||||
|     extract::Json, | ||||
|     response, | ||||
|     routing::{get, post}, | ||||
|     Router, | ||||
| }; | ||||
| use log::{debug, info, warn}; | ||||
| use rand::prelude::*; | ||||
| use serde::Serialize; | ||||
| use tokio::{net::TcpListener, time::Instant}; | ||||
| use types::{ | ||||
| use battlesnake::types::{ | ||||
|     simulation::Board, | ||||
|     wire::{Request, Response}, | ||||
|     Direction, | ||||
| }; | ||||
| use log::{debug, info, warn}; | ||||
| use rand::prelude::*; | ||||
| use serde::Serialize; | ||||
| use tokio::{net::TcpListener, time::Instant}; | ||||
|  | ||||
| #[tokio::main] | ||||
| async fn main() { | ||||
|   | ||||
| @@ -6,11 +6,12 @@ pub mod wire; | ||||
|  | ||||
| #[derive(Debug, PartialEq, Eq, Clone, Copy, Deserialize)] | ||||
| pub struct Coord { | ||||
|     x: u8, | ||||
|     y: u8, | ||||
|     pub x: u8, | ||||
|     pub y: u8, | ||||
| } | ||||
|  | ||||
| impl Coord { | ||||
|     #[must_use] | ||||
|     pub fn apply(self, direction: Direction) -> Option<Self> { | ||||
|         match direction { | ||||
|             Direction::Up => self.y.checked_add(1).map(|y| Self { y, x: self.x }), | ||||
| @@ -20,7 +21,8 @@ impl Coord { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn wrapping_apply(mut self, direction: Direction) -> Self { | ||||
|     #[must_use] | ||||
|     pub const fn wrapping_apply(mut self, direction: Direction) -> Self { | ||||
|         match direction { | ||||
|             Direction::Up => self.y = self.y.wrapping_add(1), | ||||
|             Direction::Down => self.y = self.y.wrapping_sub(1), | ||||
|   | ||||
| @@ -121,20 +121,29 @@ impl Display for Board { | ||||
| } | ||||
|  | ||||
| impl Board { | ||||
|     #[must_use] | ||||
|     pub const fn turn(&self) -> u32 { | ||||
|         self.turn | ||||
|     } | ||||
|  | ||||
|     #[must_use] | ||||
|     pub fn num_snakes(&self) -> usize { | ||||
|         self.snakes.len() | ||||
|     } | ||||
|  | ||||
|     #[must_use] | ||||
|     pub fn is_food(&self, tile: Coord) -> bool { | ||||
|         let index = self.coord_to_linear(tile); | ||||
|         self.food[index] | ||||
|     } | ||||
|  | ||||
|     #[must_use] | ||||
|     pub fn is_hazard(&self, tile: Coord) -> bool { | ||||
|         let index = self.coord_to_linear(tile); | ||||
|         self.hazard[index] | ||||
|     } | ||||
|  | ||||
|     #[must_use] | ||||
|     pub fn is_free(&self, tile: Coord) -> bool { | ||||
|         if !(tile.x < self.width && tile.y < self.height) { | ||||
|             return false; | ||||
| @@ -182,6 +191,7 @@ impl Board { | ||||
|         self.eliminate_snake_standard(); | ||||
|         self.update_free_map(); | ||||
|         self.spawn_food(); | ||||
|         self.turn += 1; | ||||
|     } | ||||
|  | ||||
|     fn move_standard(&mut self, actions: &[(u8, Direction)]) { | ||||
| @@ -232,22 +242,30 @@ impl Board { | ||||
|     } | ||||
|  | ||||
|     fn feed_snakes_standard(&mut self) { | ||||
|         let mut eaten_food = vec![]; | ||||
|         for i in 0..self.snakes.len() { | ||||
|             let head = self.snakes[i].head(); | ||||
|             if self.is_in_bounds(head) { | ||||
|                 let head_index = self.coord_to_linear(head); | ||||
|                 if self.food[head_index] { | ||||
|                     eaten_food.push(head_index); | ||||
|                     let snake = &mut self.snakes[i]; | ||||
|                     snake.health = 100; | ||||
|                     let tail = snake.tail(); | ||||
|                     snake.body.push_back(tail); | ||||
|         if self.constrictor { | ||||
|             for snake in &mut self.snakes { | ||||
|                 snake.health = 100; | ||||
|                 let tail = snake.tail(); | ||||
|                 snake.body.push_back(tail); | ||||
|             } | ||||
|         } else { | ||||
|             let mut eaten_food = vec![]; | ||||
|             for i in 0..self.snakes.len() { | ||||
|                 let head = self.snakes[i].head(); | ||||
|                 if self.is_in_bounds(head) { | ||||
|                     let head_index = self.coord_to_linear(head); | ||||
|                     if self.food[head_index] { | ||||
|                         eaten_food.push(head_index); | ||||
|                         let snake = &mut self.snakes[i]; | ||||
|                         snake.health = 100; | ||||
|                         let tail = snake.tail(); | ||||
|                         snake.body.push_back(tail); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         for food_index in eaten_food { | ||||
|             self.food.set(food_index, false); | ||||
|             for food_index in eaten_food { | ||||
|                 self.food.set(food_index, false); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user