Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ureq = { version = "2.9.6", features = ["json"] }
serde_json = "1.0.114"
rand = "0.8.5"
ureq = { version = "3.2.0", features = ["json"] }
serde_json = "1.0.149"
rand = "0.10.0"

[dev-dependencies]
criterion = "0.3.4"
criterion = "0.8.2"

[[bench]]
name = "othello"
Expand Down
26 changes: 22 additions & 4 deletions benches/othello.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use criterion::{criterion_group, criterion_main, Criterion};
use rusty_othello_ai::{
mcts::MCTS,
othello::{simulate_game, State},
};
use std::time::Duration;

pub fn bench_game(c: &mut Criterion) {
let mut group = c.benchmark_group("game");
group
.sample_size(1000)
.measurement_time(Duration::from_secs(10));
group.bench_function("play game 1", |b| {
b.iter(|| {
let mut state = State::new();
let mut actions = state.get_actions();
while !actions.is_empty() {
state = state.do_action(Some(actions[0].clone()));
actions = state.get_actions();
}
})
});

group.finish()
}

pub fn bench_simulate_game(c: &mut Criterion) {
let mut group = c.benchmark_group("simulate_game");
group
.sample_size(1000)
.measurement_time(Duration::from_secs(10));
let game_state = rusty_othello_ai::othello::State::new();
group.bench_function("simulate game 1", |b| {
b.iter(|| simulate_game(black_box(&mut game_state.clone())))
b.iter(|| simulate_game(&State::new()))
});

group.finish()
Expand All @@ -30,5 +48,5 @@ pub fn bench_mcts_search(c: &mut Criterion) {
group.finish()
}

criterion_group!(game, bench_simulate_game, bench_mcts_search);
criterion_group!(game, bench_game, bench_simulate_game, bench_mcts_search);
criterion_main!(game);
19 changes: 12 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use std::process::exit;
use std::time::Duration;
use std::usize;
use std::{borrow::Borrow, thread::sleep};
use ureq::Response;
use ureq::http::Response;
use ureq::Body;
mod console_game;
mod mcts;
mod othello;
Expand Down Expand Up @@ -91,8 +92,8 @@ fn is_my_turn(ai: &String) -> Result<bool, Box<dyn std::error::Error>> {
let url = format!("{}/turn", SERVER_URL);
match ureq::get(&url).call() {
Ok(response) => {
let body = response.into_string()?;
match body.trim() {
let mut body = response.into_body();
match &body.read_to_string()? {
// If the response is "true", it's the AI's turn and the function returns Ok(true)
x if x == ai => return Ok(true),
// If the response is "false", it's not the AI's turn and the function returns Ok(false)
Expand Down Expand Up @@ -122,7 +123,11 @@ fn get_game_state() -> State {
loop {
match get_json() {
Ok(resp) => {
return parse_state(resp.into_json().expect("Error parsing response to json"))
return parse_state(
resp.into_body()
.read_json()
.expect("Error parsing response to json"),
)
}
Err(_e) => {
sleep(delay);
Expand All @@ -135,14 +140,14 @@ fn get_game_state() -> State {

// This function makes a GET request to the server to get the current game board
// The response is returned as a Result
fn get_json() -> Result<Response, ureq::Error> {
fn get_json() -> Result<Response<Body>, ureq::Error> {
let url = format!("{}/board", SERVER_URL);
let resp = ureq::get(&url).call()?;
Ok(resp)
}

// Function to send the AI's move to the server
fn send_move(player: &String, ai_move: Option<Action>) -> Result<Response, ureq::Error> {
fn send_move(player: &String, ai_move: Option<Action>) -> Result<Response<Body>, ureq::Error> {
let resp;
let url;
// If the AI has a move, format the URL for the setChoice endpoint
Expand All @@ -168,5 +173,5 @@ fn send_progress(current: usize, total: usize, ai_color: &Color) {
Color::WHITE => "true",
};
let url = format!("{}/AIStatus/{}/{}/{}", SERVER_URL, current, total, color);
_ = ureq::post(&url).call();
_ = ureq::post(&url);
}
6 changes: 3 additions & 3 deletions src/mcts.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::othello::{simulate_game, Action, Color, State};
use rand::Rng;
use rand::prelude::*;
use std::collections::HashMap;

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -153,8 +153,8 @@ impl MCTS {
return self.size - 1;
} else {
// Pick one random action to expand (not all at once)
let mut rng = rand::thread_rng();
let action_index = rng.gen_range(0..untried_actions.len());
let mut rng = rand::rng();
let action_index = rng.random_range(0..untried_actions.len());
let action = untried_actions[action_index].clone();

// Remove this action from untried_actions in the original node
Expand Down
7 changes: 3 additions & 4 deletions src/othello.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rand::Rng;
use rand::prelude::*;
use std::{fmt, isize, u16, usize};

const BOARD_SIZE: usize = 8;
Expand Down Expand Up @@ -400,7 +400,6 @@ impl Action {
}
}

#[inline]
pub fn simulate_game(state: &State) -> isize {
let mut test_state = state.clone();
let mut consecutive_skips = 0;
Expand All @@ -419,8 +418,8 @@ pub fn simulate_game(state: &State) -> isize {
current_action = None;
consecutive_skips += 1;
} else {
let mut rng = rand::thread_rng();
let index = rng.gen_range(0..test_actions.len());
let mut rng = rand::rng();
let index = rng.random_range(0..test_actions.len());
current_action = Some(test_actions[index].clone());
consecutive_skips = 0;
}
Expand Down
Loading