mirror of
https://git.kittycat.homes/zoe/reversi.git
synced 2024-08-15 03:27:19 +00:00
Compare commits
No commits in common. "58066c8abc9bdf7f0e74bb7f6442fe446d335936" and "dce8bc5d9202fed4b086e400cd550c2749bc390f" have entirely different histories.
58066c8abc
...
dce8bc5d92
5 changed files with 33 additions and 133 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -1222,7 +1222,6 @@ dependencies = [
|
||||||
"rocket_codegen",
|
"rocket_codegen",
|
||||||
"rocket_http",
|
"rocket_http",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
|
||||||
"state",
|
"state",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"time",
|
"time",
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rocket = {version = "0.5.0-rc.1", features= ["json"]}
|
rocket = "0.5.0-rc.1"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
clap = { version = "3.0.6", features = ["derive"] }
|
clap = { version = "3.0.6", features = ["derive"] }
|
||||||
rocket_dyn_templates = {version="0.1.0-rc.1", features= ["handlebars"] }
|
rocket_dyn_templates = {version="0.1.0-rc.1", features= ["handlebars"] }
|
||||||
|
|
|
||||||
78
src/main.rs
78
src/main.rs
|
|
@ -4,16 +4,14 @@ extern crate rocket;
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
use rocket::fs::{relative, FileServer};
|
use rocket::fs::{relative, FileServer};
|
||||||
use rocket::response::stream::{Event, EventStream};
|
use rocket::{State, Shutdown};
|
||||||
|
use rocket::serde::{Serialize, Deserialize};
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
|
use rocket::form::Form;
|
||||||
use std::{
|
use rocket::tokio::sync::broadcast::{channel, Sender, error::RecvError};
|
||||||
collections::HashMap,
|
use rocket::response::stream::{EventStream, Event, TextStream};
|
||||||
mem::drop,
|
use std::{collections::HashMap, mem::drop, sync::Mutex};
|
||||||
sync::{mpsc, Mutex, RwLock},
|
|
||||||
};
|
|
||||||
|
|
||||||
mod names;
|
mod names;
|
||||||
mod rooms;
|
mod rooms;
|
||||||
|
|
@ -22,8 +20,16 @@ mod templates;
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref ARGS: Args = Args::parse();
|
static ref ARGS: Args = Args::parse();
|
||||||
static ref ROOMS: Mutex<HashMap<String, rooms::Room>> = Mutex::new(HashMap::new());
|
static ref ROOMS: Mutex<HashMap<String, rooms::Room>> = Mutex::new(HashMap::new());
|
||||||
/// String is the room list
|
}
|
||||||
static ref PLAYS: Mutex<HashMap<String, Vec<rooms::Board>>> = Mutex::new(HashMap::new());
|
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, FromForm, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(test, derive(PartialEq, UriDisplayQuery))]
|
||||||
|
#[serde(crate = "rocket::serde")]
|
||||||
|
struct Play {
|
||||||
|
pub roomname: String,
|
||||||
|
pub position: String,
|
||||||
|
pub player1: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -48,7 +54,7 @@ fn rocket() -> _ {
|
||||||
rocket::custom(config)
|
rocket::custom(config)
|
||||||
.attach(Template::fairing())
|
.attach(Template::fairing())
|
||||||
.mount("/", FileServer::from(relative!("static")))
|
.mount("/", FileServer::from(relative!("static")))
|
||||||
.mount("/", routes![index, room, stream, play])
|
.mount("/", routes![index, room, stream, post])
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -102,6 +108,7 @@ async fn room(roomname: &str, token: usize, player1: bool) -> Template {
|
||||||
// the room is real and the token is correct
|
// the room is real and the token is correct
|
||||||
if room.token == token {
|
if room.token == token {
|
||||||
drop(rooms);
|
drop(rooms);
|
||||||
|
//TODO: placeholder
|
||||||
templates::get_room(roomname, token, player1)
|
templates::get_room(roomname, token, player1)
|
||||||
}
|
}
|
||||||
// the room is real but the token is incorrect
|
// the room is real but the token is incorrect
|
||||||
|
|
@ -117,47 +124,20 @@ async fn room(roomname: &str, token: usize, player1: bool) -> Template {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//*
|
#[get("/stream")]
|
||||||
//sends new board if there have been updates
|
async fn stream(queue: &State<Sender<Play>>, mut end: Shutdown) -> TextStream![String]{
|
||||||
//*
|
let mut rx = queue.subscribe();
|
||||||
#[get("/stream/<roomname>/<token>")]
|
TextStream! {
|
||||||
async fn stream(roomname: String, token: usize) -> EventStream![] {
|
|
||||||
let roomlist = ROOMS.lock().unwrap();
|
|
||||||
drop(roomlist);
|
|
||||||
EventStream! {
|
|
||||||
loop {
|
loop {
|
||||||
// TODO
|
yield "hello!".to_string();
|
||||||
// check if there are any new events, and then if the room token is correct
|
|
||||||
// if that's the case send the current playing board
|
|
||||||
// otherwise don't do anything
|
|
||||||
yield Event::json(&"oof".to_string());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//*
|
/// Receive a message from a form submission and broadcast it to any receivers.
|
||||||
// adds new boards to the send queue after calculating move
|
#[post("/message", data = "<form>")]
|
||||||
//*
|
fn post(form: Form<Play>, queue: &State<Sender<Play>>) {
|
||||||
#[post("/play?<roomname>&<token>&<player1>&<x>&<y>")]
|
// A send 'fails' if there are no active subscribers. That's okay.
|
||||||
fn play(roomname: &str, token: usize, player1: bool, x: u8, y: u8) {
|
let _res = queue.send(form.into_inner());
|
||||||
// get room mutex
|
|
||||||
let mut roomlist = ROOMS.lock().unwrap();
|
|
||||||
// check if room is legal
|
|
||||||
if rooms::room_and_token_correct(&roomlist, &roomname, &token) {
|
|
||||||
let board = &roomlist.get_mut(roomname).unwrap().board;
|
|
||||||
if board.play_is_legal(&x, &y, &player1) {
|
|
||||||
// change the board by making a new play
|
|
||||||
board.make_play(&x, &y);
|
|
||||||
let mut playlist = PLAYS.lock().unwrap();
|
|
||||||
// if the board doesn't exist yet, make a new one
|
|
||||||
if !(playlist.contains_key(roomname)) {
|
|
||||||
let rn = roomname.to_string();
|
|
||||||
playlist.insert(rn, vec![]);
|
|
||||||
}
|
|
||||||
// add new board to the play queue
|
|
||||||
playlist.get_mut(roomname).unwrap().push(board.clone());
|
|
||||||
drop(playlist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
drop(roomlist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
85
src/rooms.rs
85
src/rooms.rs
|
|
@ -1,100 +1,21 @@
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use rocket::serde::{Deserialize, Serialize};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Room {
|
pub struct Room {
|
||||||
pub token: usize,
|
pub token: usize,
|
||||||
pub full: bool,
|
pub full: bool,
|
||||||
pub play_queue: Vec<String>,
|
pub play_queue: Vec<String>,
|
||||||
pub board: Board,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Room {
|
impl Room {
|
||||||
pub fn new() -> Room {
|
pub fn new() -> Room {
|
||||||
// generate room token
|
// generate room token
|
||||||
let token: usize = thread_rng().gen();
|
let tok: usize = thread_rng().gen();
|
||||||
|
// flip coin to see who starts
|
||||||
Room {
|
Room {
|
||||||
full: false,
|
full: false,
|
||||||
token,
|
token: tok,
|
||||||
play_queue: vec![],
|
play_queue: vec![],
|
||||||
board: Board::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn room_and_token_correct(
|
|
||||||
rooms: &HashMap<String, Room>,
|
|
||||||
roomname: &str,
|
|
||||||
token: &usize,
|
|
||||||
) -> bool {
|
|
||||||
if rooms.contains_key(roomname) {
|
|
||||||
if &rooms.get(roomname).unwrap().token == token {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, FromForm, Serialize, Deserialize)]
|
|
||||||
#[cfg_attr(test, derive(PartialEq, UriDisplayQuery))]
|
|
||||||
#[serde(crate = "rocket::serde")]
|
|
||||||
pub struct Play {
|
|
||||||
pub roomname: String,
|
|
||||||
#[field(validate = len(2...2))]
|
|
||||||
pub position: String,
|
|
||||||
pub player1: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
|
||||||
#[serde(crate = "rocket::serde")]
|
|
||||||
pub struct Board {
|
|
||||||
pub position: String,
|
|
||||||
pub player1: bool,
|
|
||||||
pub fields: Vec<Vec<Field>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Board {
|
|
||||||
pub fn new() -> Board {
|
|
||||||
let mut rng = thread_rng();
|
|
||||||
let mut fields: Vec<Vec<Field>> = vec![];
|
|
||||||
let mut i: u8 = 0;
|
|
||||||
while i <= 8 {
|
|
||||||
let mut inner: Vec<Field> = vec![];
|
|
||||||
let mut i_inner: u8 = 0;
|
|
||||||
while i_inner <= 8 {
|
|
||||||
inner.push(Field::new());
|
|
||||||
i_inner += 1;
|
|
||||||
}
|
|
||||||
fields.push(inner);
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
Board {
|
|
||||||
player1: rng.gen_bool(1.0 / 2.0),
|
|
||||||
// TODO change this!!! this doesn't make sense! i just put this here for testing
|
|
||||||
position: "".to_string(),
|
|
||||||
fields,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn make_play(&self, x: &u8, y: &u8) {
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
pub fn play_is_legal(&self, x: &u8, y: &u8, player1: &bool) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, FromForm, Serialize, Deserialize)]
|
|
||||||
#[cfg_attr(test, derive(PartialEq, UriDisplayQuery))]
|
|
||||||
#[serde(crate = "rocket::serde")]
|
|
||||||
pub struct Field {
|
|
||||||
owner: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl Field {
|
|
||||||
fn new() -> Field {
|
|
||||||
Field { owner: 0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue