Skip to content
This repository has been archived by the owner on Jan 22, 2024. It is now read-only.

Make cold-clear tetrio-garbage aware #28

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
eb1235b
Implement counting of b2b chain
Seppel3210 Jul 17, 2021
9c08e72
Implement tetr.io garbage
Seppel3210 Jul 17, 2021
2461a55
Implement tetr.io evaluation
Seppel3210 Jul 18, 2021
f0f9b2b
Add tetr.io values to optimizer
Seppel3210 Jul 18, 2021
3647f22
Change from f32 to f64 (what JS uses)
Seppel3210 Jul 20, 2021
6e45f05
Always add (combo_)garbage to eval for tetrio
Seppel3210 Jul 20, 2021
d84f863
Modify eval
Seppel3210 Aug 10, 2021
425bc91
Copy weights from changed.rs to standard.rs
Seppel3210 Aug 10, 2021
3190b91
make diskbook only available on desktop
MinusKelvin Aug 20, 2021
cff85e5
make compile on web again
MinusKelvin Aug 20, 2021
a6c469f
make tbp interface work on web hopefully
MinusKelvin Aug 20, 2021
629dec6
update game-util, add windows subsystem annotation
MinusKelvin Sep 10, 2021
7b4abc9
add libgtk-3 to CI dependencies
MinusKelvin Sep 10, 2021
24ef169
add required [lib] section and entry point for web tbp
MinusKelvin Oct 12, 2021
295a167
add show_plan option
MinusKelvin Oct 26, 2021
d167820
Add garbage messiness config option
MinusKelvin Nov 21, 2021
bf37ad9
correct tbp version (fixes #31)
MinusKelvin Jan 5, 2022
13b097a
add Board::set_cell_color
MinusKelvin Jan 9, 2022
60f2784
Merge tetrio_garbage from Seppel3210/cold-clear
Seppel3210 Jan 10, 2022
f891afe
Refactor deal_garbage into send_garbage and receive_garbage
Seppel3210 Jan 10, 2022
85b8b6a
Implement tetrio_garbage in battle
Seppel3210 Jan 10, 2022
47e4e27
Fix blocking for ppt (whoops)
Seppel3210 Jan 10, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/client.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Install libraries
run: sudo apt install libasound2-dev libudev-dev
run: sudo apt install libasound2-dev libudev-dev libgtk-3-dev
- name: Build
run: cargo build --release --bin cc-client
- name: Artifact
Expand Down
6 changes: 5 additions & 1 deletion battle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ edition = "2018"

[dependencies]
libtetris = { path = "../libtetris" }
ordered-float = { version = "2.8.0", features = ["serde"] }
rand = "0.7.0"
rand_pcg = "0.2.0"
serde = { version = "1", features = ["derive"] }
serde = { version = "1", features = ["derive"] }

[features]
tetrio_garbage = []
27 changes: 19 additions & 8 deletions battle/src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,17 @@ impl Game {
GameState::LineClearDelay(0) => {
self.state = GameState::SpawnDelay(self.config.spawn_delay);
let mut events = vec![Event::EndOfLineClearDelay];
#[cfg(not(feature = "tetrio_garbage"))]
if !self.config.garbage_blocking {
self.deal_garbage(&mut events, garbage_rng);
self.send_garbage(&mut events);
self.receive_garbage(&mut events, garbage_rng);
}
#[cfg(feature = "tetrio_garbage")]
{
self.send_garbage(&mut events);
if !self.config.garbage_blocking {
self.receive_garbage(&mut events, garbage_rng);
}
}
events
}
Expand Down Expand Up @@ -394,27 +403,32 @@ impl Game {
events.push(Event::GameOver);
} else if locked.cleared_lines.is_empty() {
self.state = GameState::SpawnDelay(self.config.spawn_delay);
self.deal_garbage(events, garbage_rng);
self.send_garbage(events);
self.receive_garbage(events, garbage_rng);
} else {
self.attacking += locked.garbage_sent;
self.state = GameState::LineClearDelay(self.config.line_clear_delay);
}
}

fn deal_garbage(&mut self, events: &mut Vec<Event>, rng: &mut impl Rng) {
fn send_garbage(&mut self, events: &mut Vec<Event>) {
if self.attacking > self.garbage_queue {
self.attacking -= self.garbage_queue;
events.push(Event::GarbageSent(self.attacking));
self.garbage_queue = 0;
} else {
self.garbage_queue -= self.attacking;
self.attacking = 0;
}
self.attacking = 0;
}

fn receive_garbage(&mut self, events: &mut Vec<Event>, rng: &mut impl Rng) {
if self.garbage_queue > 0 {
let mut dead = false;
let mut col = rng.gen_range(0, 10);
let mut garbage_columns = vec![];
for _ in 0..self.garbage_queue.min(self.config.max_garbage_add) {
if rng.gen_bool(1.0 / 3.0) {
if rng.gen_bool(self.config.garbage_messiness.into_inner()) {
col = rng.gen_range(0, 10);
}
garbage_columns.push(col);
Expand All @@ -426,9 +440,6 @@ impl Game {
events.push(Event::GameOver);
self.state = GameState::GameOver;
}
} else if self.attacking > 0 {
events.push(Event::GarbageSent(self.attacking));
self.attacking = 0;
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions battle/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use ordered_float::NotNan;
use serde::{Deserialize, Serialize};

mod battle;
Expand All @@ -24,6 +25,7 @@ pub struct GameConfig {
pub max_garbage_add: u32,
pub move_lock_rule: u32,
pub garbage_blocking: bool,
pub garbage_messiness: NotNan<f64>,
}

impl Default for GameConfig {
Expand All @@ -41,6 +43,7 @@ impl Default for GameConfig {
max_garbage_add: 10,
move_lock_rule: 15,
garbage_blocking: false,
garbage_messiness: NotNan::new(0.3).unwrap(),
}
}
}
Expand All @@ -59,6 +62,7 @@ impl GameConfig {
max_garbage_add: 20,
move_lock_rule: 15,
garbage_blocking: true,
garbage_messiness: NotNan::new(0.0).unwrap(),
}
}
}
3 changes: 3 additions & 0 deletions bot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ webutil = { git = "https://github.com/MinusKelvin/webutil", rev = "5a54126" }
futures-util = "0.3"
getrandom = { version = "0.1", features = ["wasm-bindgen"] }
console_error_panic_hook = "0.1.6"

[features]
tetrio_garbage = ["libtetris/tetrio_garbage"]
11 changes: 10 additions & 1 deletion bot/src/dag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ struct SimplifiedBoard<'c> {
combo: u32,
bag: EnumSet<Piece>,
reserve: Piece,
#[cfg(feature = "tetrio_garbage")]
back_to_back: u32,
#[cfg(not(feature = "tetrio_garbage"))]
back_to_back: bool,
reserve_is_hold: bool,
}
Expand Down Expand Up @@ -599,7 +602,13 @@ impl<E: Evaluation<R> + 'static, R: Clone + 'static> DagState<E, R> {
plan
}

pub fn reset(&mut self, field: [[bool; 10]; 40], b2b: bool, combo: u32) -> Option<i32> {
pub fn reset(
&mut self,
field: [[bool; 10]; 40],
#[cfg(feature = "tetrio_garbage")] b2b: u32,
#[cfg(not(feature = "tetrio_garbage"))] b2b: bool,
combo: u32,
) -> Option<i32> {
let garbage_lines;
if b2b == self.board.b2b_bonus && combo == self.board.combo {
let mut b = Board::<u16>::new();
Expand Down
16 changes: 8 additions & 8 deletions bot/src/desktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ impl Interface {
/// Note: combo is not the same as the displayed combo in guideline games. Here, it is the
/// number of consecutive line clears achieved. So, generally speaking, if "x Combo" appears
/// on the screen, you need to use x+1 here.
pub fn reset(&self, field: [[bool; 10]; 40], b2b_active: bool, combo: u32) {
self.send
.send(BotMsg::Reset {
field,
b2b: b2b_active,
combo,
})
.ok();
pub fn reset(
&self,
field: [[bool; 10]; 40],
#[cfg(feature = "tetrio_garbage")] b2b: u32,
#[cfg(not(feature = "tetrio_garbage"))] b2b: bool,
combo: u32,
) {
self.send.send(BotMsg::Reset { field, b2b, combo }).ok();
}

/// Specifies a line that Cold Clear should analyze before making any moves.
Expand Down
110 changes: 103 additions & 7 deletions bot/src/evaluation/changed.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
use libtetris::*;
use serde::{Deserialize, Serialize};

use libtetris::*;

use super::*;

#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(default)]
pub struct Standard {
#[cfg(feature = "tetrio_garbage")]
pub b2b_chain: i32,
#[cfg(feature = "tetrio_garbage")]
pub b2b_chain_log: i32,
#[cfg(feature = "tetrio_garbage")]
pub combo_multiplier: i32,

pub back_to_back: i32,
pub bumpiness: i32,
pub bumpiness_sq: i32,
Expand Down Expand Up @@ -49,6 +57,13 @@ pub struct Standard {
impl Default for Standard {
fn default() -> Self {
Standard {
#[cfg(feature = "tetrio_garbage")]
b2b_chain: 0,
#[cfg(feature = "tetrio_garbage")]
b2b_chain_log: 0,
#[cfg(feature = "tetrio_garbage")]
combo_multiplier: 0,

back_to_back: 52,
bumpiness: -24,
bumpiness_sq: -7,
Expand Down Expand Up @@ -92,6 +107,7 @@ impl Default for Standard {
}

impl Standard {
#[cfg(not(feature = "tetrio_garbage"))]
pub fn fast_config() -> Self {
Standard {
back_to_back: 10,
Expand Down Expand Up @@ -132,6 +148,67 @@ impl Standard {
sub_name: None,
}
}

#[cfg(feature = "tetrio_garbage")]
pub fn fast_config() -> Self {
Standard {
b2b_chain: 214,
b2b_chain_log: 1,
combo_multiplier: 41,
back_to_back: 56,
bumpiness: 11,
bumpiness_sq: -26,
row_transitions: -124,
height: -58,
top_half: -765,
top_quarter: -499,
jeopardy: -5,
cavity_cells: -168,
cavity_cells_sq: -33,
overhang_cells: -54,
overhang_cells_sq: 14,
covered_cells: 9,
covered_cells_sq: -17,
tslot: [
112,
151,
35,
380,
],
well_depth: 74,
max_well_depth: 31,
well_column: [
24,
6,
24,
56,
23,
310,
85,
142,
118,
33,
],
b2b_clear: 128,
clear1: -141,
clear2: -93,
clear3: -63,
clear4: 385,
tspin1: 126,
tspin2: 559,
tspin3: 602,
mini_tspin1: -157,
mini_tspin2: -215,
perfect_clear: 988,
combo_garbage: 166,
move_time: -4,
wasted_t: -188,
use_bag: true,
timed_jeopardy: true,
stack_pc_damage: true,
sub_name: None,
}
}
}

impl Evaluator for Standard {
Expand All @@ -156,8 +233,8 @@ impl Evaluator for Standard {
for mv in candidates.into_iter() {
if incoming == 0
|| mv.board.column_heights()[3..6]
.iter()
.all(|h| incoming as i32 - mv.lock.garbage_sent as i32 + h <= 20)
.iter()
.all(|h| incoming as i32 - mv.lock.garbage_sent as i32 + h <= 20)
{
return mv;
}
Expand Down Expand Up @@ -189,6 +266,12 @@ impl Evaluator for Standard {
if lock.b2b {
acc_eval += self.b2b_clear;
}

#[cfg(feature = "tetrio_garbage")]
if lock.combo.is_some() {
acc_eval += self.combo_garbage * lock.garbage_sent as i32;
}
#[cfg(not(feature = "tetrio_garbage"))]
if let Some(combo) = lock.combo {
let combo = combo.min(11) as usize;
acc_eval += self.combo_garbage * libtetris::COMBO_GARBAGE[combo] as i32;
Expand Down Expand Up @@ -240,10 +323,23 @@ impl Evaluator for Standard {
};
acc_eval += self.move_time * move_time;

#[cfg(feature = "tetrio_garbage")]
if board.b2b_bonus > 0 {
transient_eval += self.back_to_back;
}
#[cfg(not(feature = "tetrio_garbage"))]
if board.b2b_bonus {
transient_eval += self.back_to_back;
}

#[cfg(feature = "tetrio_garbage")]
{
transient_eval += self.b2b_chain * board.b2b_bonus as i32;
transient_eval += (self.b2b_chain_log as f32 * (board.b2b_bonus as f32).ln_1p()) as i32;

transient_eval += self.combo_multiplier * board.combo as i32;
}

let highest_point = *board.column_heights().iter().max().unwrap() as i32;
transient_eval += self.top_quarter * (highest_point - 15).max(0);
transient_eval += self.top_half * (highest_point - 10).max(0);
Expand Down Expand Up @@ -321,10 +417,10 @@ impl Evaluator for Standard {
if self.row_transitions != 0 {
transient_eval += self.row_transitions
* (0..40)
.map(|y| *board.get_row(y))
.map(|r| (r | 0b1_00000_00000) ^ (1 | r << 1))
.map(|d| d.count_ones() as i32)
.sum::<i32>();
.map(|y| *board.get_row(y))
.map(|r| (r | 0b1_00000_00000) ^ (1 | r << 1))
.map(|d| d.count_ones() as i32)
.sum::<i32>();
}

if self.bumpiness | self.bumpiness_sq != 0 {
Expand Down
Loading