256 lines
7.2 KiB
Rust
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;
|
||
|
}
|