bugfixing

This commit is contained in:
Tao Tien 2026-03-04 23:05:56 -08:00
parent b66a4e63f1
commit 3457e0d024
13 changed files with 495 additions and 444 deletions

View file

@ -5,9 +5,12 @@ use spacetimedb::{
ReducerContext, ScheduleAt::Interval, Table as _, rand::seq::SliceRandom, reducer,
};
use crate::tables::{
DbTile, Lobby, LobbyTimer, PlayerClock, PlayerHand, Wall, bot, game_timer, lobby as _,
player_clock, player_config, player_hand, tile, user, wall,
use crate::{
reducers::hand::{discard_tile, discard_tile_private},
tables::{
DbTile, Lobby, LobbyTimer, PlayerClock, PlayerHand, Wall, bot, game_timer, lobby as _,
player_clock, player_config, player_hand, tile, user, wall,
},
};
use jong_types::{GameState, TurnState};
@ -139,6 +142,14 @@ pub fn advance_game_private(
ctx.db.player_clock().player_id().update(clock);
} else {
// TODO bot / auto discard
discard_tile_private(
ctx,
lobby.id,
ctx.db.player_config().id().find(curr_player).unwrap(),
hand.working_tile.unwrap().id,
)
.unwrap();
return Ok(());
}
}
TurnState::Menzen => {}

View file

@ -9,14 +9,26 @@ use crate::tables::*;
#[reducer]
pub fn discard_tile(ctx: &ReducerContext, tile_id: u32) -> Result<(), String> {
let player = ctx.db.user().identity().find(ctx.sender()).unwrap();
let config = ctx.db.player_config().id().find(player.config_id).unwrap();
discard_tile_private(ctx, player.lobby_id, config, tile_id)?;
Ok(())
}
pub(crate) fn discard_tile_private(
ctx: &ReducerContext,
lobby_id: u32,
player_config: PlayerConfig,
tile_id: u32,
) -> Result<(), String> {
let mut hand = ctx
.db
.player_hand()
.player_id()
.find(player.config_id)
.find(player_config.id)
.unwrap();
// TODO we can probably remove a buncha these errors
let dealt = ctx.db.tile().id().find(tile_id).unwrap();
let drawn = hand.working_tile.unwrap();
@ -27,13 +39,7 @@ pub fn discard_tile(ctx: &ReducerContext, tile_id: u32) -> Result<(), String> {
// dealt from hand
let dealt = hand.hand.remove(i);
hand.hand.push(drawn);
if ctx
.db
.player_config()
.id()
.find(player.config_id)
.is_some_and(|c| c.sort)
{
if player_config.sort {
hand.hand.sort_by_key(|t| t.tile);
}
@ -48,24 +54,15 @@ pub fn discard_tile(ctx: &ReducerContext, tile_id: u32) -> Result<(), String> {
hand.turn_state = TurnState::None;
ctx.db.player_hand().player_id().update(hand);
let mut clock = ctx
.db
.player_clock()
.player_id()
.find(player.config_id)
.unwrap();
clock.renew();
ctx.db.player_clock().player_id().update(clock);
if let Some(mut clock) = ctx.db.player_clock().player_id().find(player_config.id) {
clock.renew();
ctx.db.player_clock().player_id().update(clock);
}
let mut lobby = ctx.db.lobby().id().find(player.lobby_id).unwrap();
let mut lobby = ctx.db.lobby().id().find(lobby_id).unwrap();
lobby.next_player();
ctx.db.lobby().id().update(lobby);
debug!(
"player {} discarded tile {:?}",
player.identity, dealt_tile.tile
);
Ok(())
}

View file

@ -1,6 +1,6 @@
use std::time::Duration;
use log::{info, warn};
use log::{debug, info, warn};
use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer};
use crate::{reducers::advance_game_private, tables::*};
@ -50,6 +50,50 @@ pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<(
Ok(())
}
#[reducer]
pub fn set_ready(ctx: &ReducerContext, ready: bool) -> Result<(), String> {
let mut user = ctx.db.user().identity().find(ctx.sender()).unwrap();
let mut player = ctx.db.player_config().id().find(user.config_id).unwrap();
player.ready = ready;
let player = ctx.db.player_config().id().update(player);
if player.ready {
debug!("player readied");
} else {
debug!("player unreadied");
}
if let Some(mut lobby) = ctx.db.lobby().id().find(user.lobby_id)
&& lobby.players.len() == 4
&& lobby.players.iter().all(|id| {
ctx.db
.player_config()
.id()
.find(id)
.is_some_and(|p| p.ready)
})
&& ctx.db.game_timer().lobby_id().find(user.lobby_id).is_none()
{
lobby.game_state = jong_types::states::GameState::Setup;
let lobby = ctx.db.lobby().id().update(lobby);
// TODO should we schedule this outside so that we can clear out stale lobbies?
let game_timer = ctx.db.game_timer().insert(LobbyTimer {
lobby_id: lobby.id,
scheduled_id: 0,
scheduled_at: spacetimedb::ScheduleAt::Interval(Duration::from_secs(1).into()),
});
advance_game_private(ctx, game_timer)?;
} else {
// TODO if lobby doesn't exist, reset player state?
// FIXME return error here
}
Ok(())
}
#[reducer]
pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> {
if lobby_id == 0 {
@ -63,7 +107,7 @@ pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> {
id: 0,
name: String::new(),
ready: true,
sort: true,
sort: false,
});
let bot = ctx.db.bot().insert(Bot {
id: 0,
@ -78,44 +122,3 @@ pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> {
Err(format!("lobby {lobby_id} doesn't exist or is full"))
}
}
#[reducer]
pub fn set_ready(ctx: &ReducerContext, ready: bool) -> Result<(), String> {
let mut user = ctx.db.user().identity().find(ctx.sender()).unwrap();
let mut player = ctx.db.player_config().id().find(user.config_id).unwrap();
player.ready = ready;
let player = ctx.db.player_config().id().update(player);
if let Some(mut lobby) = ctx.db.lobby().id().find(user.lobby_id)
&& lobby.players.len() == 4
&& lobby.players.iter().all(|id| {
ctx.db
.player_config()
.id()
.find(id)
.is_some_and(|p| p.ready)
})
{
lobby.game_state = jong_types::states::GameState::Setup;
let lobby = ctx.db.lobby().id().update(lobby);
// TODO should we schedule this outside so that we can clear out stale lobbies?
let game_timer = ctx.db.game_timer().insert(LobbyTimer {
lobby_id: lobby.id,
scheduled_id: 0,
scheduled_at: spacetimedb::ScheduleAt::Interval(Duration::from_secs(1).into()),
});
advance_game_private(ctx, game_timer)?;
} else {
// TODO if lobby doesn't exist, reset player state
user.lobby_id = 0;
user = ctx.db.user().identity().update(user);
return Err(format!("couldn't find lobby with id: {}", user.lobby_id));
}
Ok(())
}

View file

@ -7,7 +7,7 @@ use jong_types::{
use crate::reducers::advance_game_private;
#[table(accessor = user)]
#[table(accessor = user, public)]
#[table(accessor = logged_out_user)]
#[derive(Debug)]
pub struct User {
@ -18,7 +18,6 @@ pub struct User {
#[index(btree)]
pub lobby_id: u32,
#[unique]
pub config_id: u32,
}
@ -112,7 +111,7 @@ pub struct PlayerHand {
pub working_tile: Option<DbTile>,
}
#[table(accessor = game_timer, scheduled(advance_game_private), public)]
#[table(accessor = game_timer, scheduled(advance_game_private))]
pub struct LobbyTimer {
#[unique]
pub lobby_id: u32,