# KrwEmd

## Environment Setup
We provide the source code for KrwEmd, along with a Docker-based setup to ensure a consistent runtime environment.

### Step 1.1: Build the Docker Image
Navigate to the `/path/to/krwemd-env` directory and run the following command to build the Docker image:
```
sudo docker build -t krwemd-env ./ --progress=plain
```


### Step 1.2: Create and Run the Docker Container
To create a container from the image and launch an interactive shell environment, run:
```
sudo docker run --privileged -it --network host krwemd-env bash
```

Once inside the container, you will be logged in as the `root` user by default. The environment includes two main directories:
- `/root/krwemd`: Contains the project for generating various signal abstraction algorithms (or signal infoset equivalence classes).
- `/root/VariantPokerCFR_AndBR`: This project is used for applying these abstraction algorithms to strategy training and evaluating strategy exploitability.

## KrwEmd
The KrwEmd project includes example code that can generate various abstractions such as POI, KROI, PWI, KRWI, KrwEmd, Ehs, and PaEmd. Users can choose which ones to generate. All commands should be executed within the `/root/krwemd/` directory.

### Step 2.1: Generate POI, KROI, PWI, and KRWI
Run the following command to generate the respective abstractions:
```
cargo run --example generate_pwi_and_krwi --features "rust_waugh test_print"
```
The output is stored in `data/Numeral211`, which serves as the data directory for the RocksDB database.

### Step 2.2: Generate KrwEmd
Run the following command to generate the KrwEmd abstractions:
```
cargo run --example generate_krwemd --features "rust_waugh test_print"
```
The output is stored in `data/CustomCluster/Numeral211/KrwEmd`, where folder `1` contains the instance with hyperparameters $(7,5,3;5,3)$ as referenced in the paper.

### Step 2.3: Generate Ehs
Run the following command to generate the Ehs abstraction:
```
cargo run --example generate_ehs --features "rust_waugh test_print"
```
The output is stored in `data/CustomCluster/Numeral211/Ehs/1`.

### Step 2.4: Generate PaEmd
Run the following command to generate the PaEmd abstraction:
```
cargo run --example generate_paemd --features "rust_waugh test_print"
```
The output is stored in `data/CustomCluster/Numeral211/PaEmd/1`.

## VariantPokerCFR_AndBR

After generating the signal abstraction data, we use **CSMCCFR** (Chance Sampling Monte Carlo Counterfactual Regret Minimization) to train the strategies. By validating the exploitability of these strategies, we can evaluate the effectiveness of each abstraction algorithm.

First, navigate to the `VariantPokerCFR_AndBR` directory and build the project by running the following command:
```
cd /root/VariantPokerCFR_AndBR && cmake -B build -S .
```

### Step 3.1 PWI, KRWI, KROI
复制抽象数据
```
mkdir -p data/full_resolution_abstraction && cp -r /root/krwemd/data/Numeral211 /root/VariantPokerCFR_AndBR/data/full_resolution_abstraction/
```
#### Step 3.1.1 PWI
编译运行
```
cmake --build build --target numeral211_train_with_br_pwi
nohup stdbuf -o0 ./build/numeral211_train_with_br_pwi --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 50209 --logs 18 &
```
结果输出到`data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_pwi.csv`

#### Step 3.1.2 KRWI
编译运行
```
cmake --build build --target numeral211_train_with_br_krwi
nohup stdbuf -o0 ./build/numeral211_train_with_br_krwi --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 50209 --logs 18 &
```
结果输出到`data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_2rwi.csv`
#### Step 3.1.3 KROI
编译运行
```
cmake --build build --target numeral211_train_with_br_kroi
nohup stdbuf -o0 ./build/numeral211_train_with_br_kroi --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 50209 --logs 18 &
```
结果输出到`data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_2roi.csv`

### Step 3.2 KrwEmd with hyperparameters $(7,5,3;5,3)$
复制数据
```
mkdir -p data/CustomCluster/Numeral211/KrwEmd && cp -r /root/krwemd/data/CustomCluster/Numeral211/KrwEmd/1 data/CustomCluster/Numeral211/KrwEmd/
```
编译运行
```
cmake --build build --target numeral211_train_with_br_krwemd
nohup stdbuf -o0 ./build/numeral211_train_with_br_krwemd --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 50209 --logs 18 &
```
结果输出到`data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd53KrwEmd753.csv`

### Step 3.3 Ehs
复制数据
```
mkdir -p data/CustomCluster/Numeral211/Ehs && cp -r /root/krwemd/data/CustomCluster/Numeral211/Ehs/1 data/CustomCluster/Numeral211/Ehs/
```
编译运行
```
cmake --build build --target numeral211_train_with_br_ehs
nohup stdbuf -o0 ./build/numeral211_train_with_br_ehs --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 50209 --logs 18 &
```
结果输出到`data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_Ehs1.csv`

### Step 3.4 PaEmd
复制数据
```
mkdir -p data/CustomCluster/Numeral211/PaEmd && cp -r /root/krwemd/data/CustomCluster/Numeral211/PaEmd/1 data/CustomCluster/Numeral211/PaEmd/
```
编译运行
```
cmake --build build --target numeral211_train_with_br_paemd
nohup stdbuf -o0 ./build/numeral211_train_with_br_paemd --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 50209 --logs 18 &
```
结果输出到`data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_PaEmd1.csv`


**Note:** Calculating the exploitability of a strategy involves enumerating all possible game states, which makes the process extremely slow. On my machine, a single exploitability calculation takes around 4 hours, and in our experimental setup, each instance ran for a full week per pc. I recommend adjusting the parameters to reduce the number of exploitability calculations, as running it once per experiment should be sufficient to observe the results.

The provided validation environment is based on the symmetric abstraction setup used in the paper, where both players employ abstraction for strategy training. While we conducted experiments with manually configured asymmetric abstractions, we did not implement an automated code to generate such results. However, both experiments show highly consistent outcomes, so we only offer the symmetric abstraction setup here for reference.
