1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use bonsaidb::core::{
    document::{CollectionDocument, Emit},
    schema::{Collection, CollectionViewSchema, Schema, View, ViewMapResult},
};
use minority_game_shared::Choice;
use serde::{Deserialize, Serialize};

#[derive(Schema, Debug)]
#[schema(authority = "minority-game", name = "game", collections = [Player])]
pub enum GameSchema {}

#[derive(Collection, Default, Debug, Serialize, Deserialize, Clone)]
#[collection(authority = "minority-game", name = "player", views = [PlayerByScore])]
pub struct Player {
    pub choice: Option<Choice>,
    #[serde(default)]
    pub tell: Option<Choice>,
    pub stats: PlayerStats,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct PlayerStats {
    pub happiness: f32,
    pub times_went_out: u32,
    pub times_stayed_in: u32,
    #[serde(default)]
    pub times_lied: u32,
    #[serde(default)]
    pub times_told_truth: u32,
}

impl Default for PlayerStats {
    fn default() -> Self {
        Self {
            happiness: 0.5,
            times_went_out: 0,
            times_stayed_in: 0,
            times_lied: 0,
            times_told_truth: 0,
        }
    }
}

impl PlayerStats {
    pub fn score(&self) -> u32 {
        let total_games = self.times_stayed_in + self.times_went_out;
        (self.happiness * total_games as f32) as u32
    }
}

#[derive(View, Debug, Clone)]
#[view(collection = Player, name = "by-score", key = u32, value = PlayerStats)]
pub struct PlayerByScore;

impl CollectionViewSchema for PlayerByScore {
    type View = Self;

    fn version(&self) -> u64 {
        2
    }

    fn map(
        &self,
        player: CollectionDocument<<Self::View as View>::Collection>,
    ) -> ViewMapResult<Self::View> {
        player
            .header
            .emit_key_and_value(player.contents.stats.score(), player.contents.stats)
    }
}