twitchbot-rs/tests/uno_test.rs
2024-03-23 19:50:45 +01:00

256 lines
7.2 KiB
Rust

pub mod uno;
use std::sync::{Arc, Mutex as StdMutex};
use twitch_irc::message::PrivmsgMessage;
use twitchbot_rs::{Bot, ClientQueue, Command, Context};
use crate::uno::{Uno, UnoPlayer, UnoState};
use crate::uno::UnoState::Ended;
pub struct PingCommand;
impl Command for PingCommand {
type CommandPayLoad = Uno;
fn execute(&self, pl_am: Arc<StdMutex<Self::CommandPayLoad>>, ctx: Context) -> ClientQueue {
let mut queue = ClientQueue::new();
let pl = pl_am.lock().unwrap();
queue.say(ctx.channel_login.to_owned(), format!("@{} Pong!", ctx.sender.name));
queue
}
}
pub struct UnoCommand;
impl Command for UnoCommand {
type CommandPayLoad = Uno;
fn execute(&self, pl_am: Arc<StdMutex<Self::CommandPayLoad>>, ctx: PrivmsgMessage) -> ClientQueue {
let mut queue = ClientQueue::new();
let mut pl = pl_am.lock().unwrap();
if pl.state == Ended {
pl.reset(ctx.sender.name.clone());
queue.me(ctx.channel_login, format!("{} started a new uno game, type !join to join.", ctx.sender.name));
} else {
queue.me(ctx.channel_login, "Another game going on rn".to_string());
}
queue
}
}
pub struct DrawCommand;
impl Command for DrawCommand {
type CommandPayLoad = Uno;
fn execute(&self, pl_am: Arc<StdMutex<Self::CommandPayLoad>>, ctx: PrivmsgMessage) -> ClientQueue {
let mut queue = ClientQueue::new();
let args: Vec<String> = ctx.message_text.split(' ').map(|s| s.to_string()).collect();
let mut pl = pl_am.lock().unwrap();
let idx = pl.active_player;
if pl.players.get_mut(idx).unwrap().name == ctx.sender.name && args.len() > 1 {
let amount = args
.get(1)
.unwrap()
.parse::<u32>()
.unwrap_or(0);
for _ in 0..amount {
let card = pl.draw();
pl.players.get_mut(idx).unwrap().hand.push(card);
}
queue.me(ctx.channel_login, format!("{} drew {} cards.", ctx.sender.name, amount));
} else {
queue.me(ctx.channel_login, "Sender probably not active player.".to_string())
}
queue
}
}
pub struct PlaceCommand;
impl Command for PlaceCommand {
type CommandPayLoad = Uno;
fn execute(&self, pl_am: Arc<StdMutex<Self::CommandPayLoad>>, ctx: PrivmsgMessage) -> ClientQueue {
let mut queue = ClientQueue::new();
let args: Vec<String> = ctx.message_text.split(' ').map(|s| s.to_string()).collect();
let mut pl = pl_am.lock().unwrap();
let idx = pl.active_player;
if pl.players.get_mut(idx).unwrap().name == ctx.sender.name && args.len() > 1 {
let hand_idx = args
.get(1)
.unwrap()
.parse::<usize>()
.unwrap_or(0);
if hand_idx < pl.players.get_mut(idx).unwrap().hand.len() {
let card = pl.players.get_mut(idx).unwrap().take_card(hand_idx);
if card.can_stack(&pl.top) {
queue.me(ctx.channel_login, format!("{} placed {}", pl.players.get_mut(idx).unwrap().name, &card));
pl.place(card);
} else {
queue.me(ctx.channel_login, "Cant stack on that card.".to_string())
}
} else {
queue.me(ctx.channel_login, "Hand index out of range".to_string());
}
} else {
queue.me(ctx.channel_login, "Sender probably not active player.".to_string())
}
queue
}
}
pub struct JoinCommand;
impl Command for JoinCommand {
type CommandPayLoad = Uno;
fn execute(&self, pl_am: Arc<StdMutex<Self::CommandPayLoad>>, ctx: PrivmsgMessage) -> ClientQueue {
let mut queue = ClientQueue::new();
let mut pl = pl_am.lock().unwrap();
if pl.state == UnoState::NotStarted {
pl.players.push(UnoPlayer::new(ctx.sender.name.clone()));
queue.me(ctx.channel_login, format!("{} Joined the game.", ctx.sender.name));
}
queue
}
}
pub struct StartCommand;
impl Command for StartCommand {
type CommandPayLoad = Uno;
fn execute(&self, pl_am: Arc<StdMutex<Self::CommandPayLoad>>, ctx: PrivmsgMessage) -> ClientQueue {
let mut queue = ClientQueue::new();
let mut pl = pl_am.lock().unwrap();
if pl.admin == ctx.sender.name {
pl.init();
queue.me(ctx.channel_login, "Game started!".to_string());
}
queue
}
}
pub struct EndCommand;
impl Command for EndCommand {
type CommandPayLoad = Uno;
fn execute(&self, pl_am: Arc<StdMutex<Self::CommandPayLoad>>, ctx: PrivmsgMessage) -> ClientQueue {
let mut queue = ClientQueue::new();
let mut pl = pl_am.lock().unwrap();
if pl.admin == ctx.sender.name {
pl.end();
queue.me(ctx.channel_login, "Game ended!".to_string());
}
queue
}
}
pub struct HandCommand;
impl Command for HandCommand {
type CommandPayLoad = Uno;
fn execute(&self, pl_am: Arc<StdMutex<Self::CommandPayLoad>>, ctx: PrivmsgMessage) -> ClientQueue {
let mut queue = ClientQueue::new();
let args: Vec<String> = ctx.message_text.split(' ').map(|s| s.to_string()).collect();
let mut pl = pl_am.lock().unwrap();
let mut index = usize::MAX;
for (i, player) in pl.players.iter().enumerate() {
if player.name == ctx.sender.name {
index = i;
}
}
let mut card_list = String::new();
for card in pl.players.get(index).unwrap().hand.iter().enumerate() {
card_list.push_str(format!("{}: {}, ", card.0, card.1).as_str());
}
let channel: String = if ctx.sender.name == "daph" {
"daphbot".to_string()
} else {
ctx.sender.name
};
queue.say(channel, card_list);
queue
}
}
pub struct TopCommand;
impl Command for TopCommand {
type CommandPayLoad = Uno;
fn execute(&self, pl_am: Arc<StdMutex<Self::CommandPayLoad>>, ctx: PrivmsgMessage) -> ClientQueue {
let mut queue = ClientQueue::new();
let mut pl = pl_am.lock().unwrap();
queue.me(ctx.channel_login, format!("Top: {}", &pl.top));
queue
}
}
#[tokio::test]
async fn main() {
let mut u = Uno::new("mzntori".to_string());
let login = std::env::var("LOGIN").unwrap();
let oauth = std::env::var("OAUTH").unwrap();
let mut bot = Bot::new(
login.as_str(),
oauth.as_str(),
u,
);
bot.add_command("!ping".to_owned(), Box::new(PingCommand {})).await;
bot.add_command("!uno".to_owned(), Box::new(UnoCommand {})).await;
bot.add_command("!join".to_owned(), Box::new(JoinCommand {})).await;
bot.add_command("!draw".to_owned(), Box::new(DrawCommand {})).await;
bot.add_command("!start".to_owned(), Box::new(StartCommand {})).await;
bot.add_command("!end".to_owned(), Box::new(EndCommand {})).await;
bot.add_command("!place".to_owned(), Box::new(PlaceCommand {})).await;
bot.add_command("!hand".to_owned(), Box::new(HandCommand {})).await;
bot.add_command("!top".to_owned(), Box::new(TopCommand {})).await;
bot.run().await;
}