<commit_before>use std::u32;
use std::mem;
use std::cmp;
use std::hash;
use std::borrow::Borrow;
use std::cmp::Ordering;
use iter;

pub type NodeIndex = u32;
const NULL_NODE: NodeIndex = u32::MAX;

#[derive(Debug, Clone)]
pub struct Node<K, V> {
    pub lft: NodeIndex,
    pub rgt: NodeIndex,
    pub key: K,
    pub val: V,
}
impl<K, V> Node<K, V> {
    pub fn rgt(&self) -> Option<NodeIndex> {
        (self.rgt != NULL_NODE).as_option().map(|_| self.rgt)
    }
    pub fn lft(&self) -> Option<NodeIndex> {
        (self.lft != NULL_NODE).as_option().map(|_| self.lft)
    }
}
impl<K, V> Node<K, V>
    where K: Ord
{
    fn new(key: K, value: V, lft: NodeIndex, rgt: NodeIndex) -> Self {
        Node {
            key: key,
            val: value,
            lft: lft,
            rgt: rgt,
        }
    }
    fn pop(nodes: &mut Vec<Self>, root: NodeIndex) -> ((K, V), NodeIndex) {
        let children = {
            let n = &mut nodes[root as usize];
            (mem::replace(&mut n.lft, NULL_NODE), mem::replace(&mut n.rgt, NULL_NODE))
        };
        let new_root = match children {
            (NULL_NODE, NULL_NODE) => NULL_NODE,
            (lft, NULL_NODE) => lft,
            (NULL_NODE, rgt) => rgt,
            (lft, mut rgt) => {
                let lft_rgt = mem::replace(&mut nodes[lft as usize].rgt, NULL_NODE);
                if lft_rgt != NULL_NODE {
                    rgt = Node::splay_lftmost(nodes, rgt);
                    nodes[rgt as usize].lft = lft_rgt;
                }
                nodes[lft as usize].rgt = rgt;
                lft
            }
        };
        if nodes.len() as NodeIndex - 1 != root {
            let key = &nodes[nodes.len() - 1].key as *const _;
            let _ = Node::splay(nodes, new_root, unsafe { &*key });
            let last = nodes.pop().unwrap();
            let old = mem::replace(&mut nodes[root as usize], last);
            ((old.key, old.val), root)
        } else {
            (nodes.pop().map(|n| (n.key, n.val)).unwrap(), new_root)
        }
    }
    fn splay<Q: ?Sized>(nodes: &mut [Self], root: NodeIndex, key: &Q) -> (NodeIndex, Ordering)
        where K: Borrow<Q>,
              Q: Ord
    {
        Node::splay_by(nodes, root, |k| key.cmp(k.borrow()))
    }
    fn splay_lftmost(nodes: &mut [Self], root: NodeIndex) -> NodeIndex {
        Node::splay_by(nodes, root, |_| Ordering::Less).0
    }
    fn splay_by<F>(nodes: &mut [Self], root: NodeIndex, cmp: F) -> (NodeIndex, Ordering)
        where F: Fn(&K) -> Ordering
    {
        assert!(root != NULL_NODE);
        let mut node = root;
        let mut lft_root = NULL_NODE;
        let mut rgt_root = NULL_NODE;
        let mut order = cmp(nodes[node as usize].key.borrow());
        {
            let mut lft_rgtmost = &mut lft_root;
            let mut rgt_lftmost = &mut rgt_root;
            loop {
                match order {
                    Ordering::Less if nodes[node as usize].lft != NULL_NODE => {
                        // zig
                        let mut child = mem::replace(&mut nodes[node as usize].lft, NULL_NODE);

                        order = cmp(nodes[child as usize].key.borrow());
                        if let Ordering::Less = order {
                            if nodes[child as usize].lft != NULL_NODE {
                                // zig-zig
                                let grand_child = mem::replace(&mut nodes[child as usize].lft,
                                                               NULL_NODE);
                                nodes[node as usize].lft = nodes[child as usize].rgt;
                                nodes[child as usize].rgt = node;
                                node = child;
                                child = grand_child;
                                order = cmp(nodes[child as usize].key.borrow());
                            }
                        }
                        *rgt_lftmost = node;
                        rgt_lftmost = unsafe { &mut *(&mut nodes[node as usize].lft as *mut _) };

                        node = child;
                    }
                    Ordering::Greater if nodes[node as usize].rgt != NULL_NODE => {
                        // zag
                        let mut child = mem::replace(&mut nodes[node as usize].rgt, NULL_NODE);
                        order = cmp(nodes[child as usize].key.borrow());
                        if let Ordering::Greater = order {
                            if nodes[child as usize].rgt != NULL_NODE {
                                // zag-zag
                                let grand_child = mem::replace(&mut nodes[child as usize].rgt,
                                                               NULL_NODE);
                                nodes[node as usize].rgt = nodes[child as usize].lft;
                                nodes[child as usize].lft = node;
                                node = child;
                                child = grand_child;
                                order = cmp(nodes[child as usize].key.borrow());
                            }
                        }
                        *lft_rgtmost = node;
                        lft_rgtmost = unsafe { &mut *(&mut nodes[node as usize].rgt as *mut _) };

                        node = child;
                    }
                    _ => break,
                }
            }
            *lft_rgtmost = mem::replace(&mut nodes[node as usize].lft, NULL_NODE);
            *rgt_lftmost = mem::replace(&mut nodes[node as usize].rgt, NULL_NODE);
        }
        nodes[node as usize].lft = lft_root;
        nodes[node as usize].rgt = rgt_root;

        (node, order)
    }
}

#[derive(Debug, Clone)]
pub struct Tree<K, V> {
    root: NodeIndex,
    nodes: Vec<Node<K, V>>,
}
impl<K, V> Tree<K, V>
    where K: Ord
{
    pub fn new() -> Self {
        Tree {
            root: 0,
            nodes: Vec::new(),
        }
    }
    pub fn contains_key<Q: ?Sized>(&mut self, key: &Q) -> bool
        where K: Borrow<Q>,
              Q: Ord
    {
        if self.nodes.is_empty() {
            false
        } else {
            let (root, order) = Node::splay(&mut self.nodes, self.root, key);
            self.root = root;
            order == Ordering::Equal
        }
    }
    pub fn find_lower_bound<Q: ?Sized>(&mut self, key: &Q) -> Option<&K>
        where K: Borrow<Q>,
              Q: Ord
    {
        (!self.nodes.is_empty()).as_option().and_then(move |_| {
            let (root, order) = Node::splay(&mut self.nodes, self.root, key);
            self.root = root;
            if let Ordering::Greater = order {
                let mut root_rgt = self.nodes[self.root as usize].rgt;
                if root_rgt != NULL_NODE {
                    root_rgt = Node::splay_lftmost(&mut self.nodes, root_rgt);
                    self.nodes[self.root as usize].rgt = root_rgt;
                    Some(&self.nodes[root_rgt as usize].key)
                } else {
                    None
                }
            } else {
                Some(&self.nodes[self.root as usize].key)
            }
        })
    }
    pub fn find_upper_bound<Q: ?Sized>(&mut self, key: &Q) -> Option<&K>
        where K: Borrow<Q>,
              Q: Ord
    {
        (!self.nodes.is_empty()).as_option().and_then(move |_| {
            let (root, order) = Node::splay(&mut self.nodes, self.root, key);
            self.root = root;
            if let Ordering::Less = order {
                Some(&self.nodes[self.root as usize].key)
            } else {
                let mut root_rgt = self.nodes[self.root as usize].rgt;
                if root_rgt != NULL_NODE {
                    root_rgt = Node::splay_lftmost(&mut self.nodes, root_rgt);
                    self.nodes[self.root as usize].rgt = root_rgt;
                    Some(&self.nodes[root_rgt as usize].key)
                } else {
                    None
                }
            }
        })
    }
    pub fn get<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V>
        where K: Borrow<Q>,
              Q: Ord
    {
        self.contains_key(key).as_option().map(move |_| &mut self.nodes[self.root as usize].val)
    }
    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
        let (new_root, old_value) = if self.nodes.is_empty() {
            self.nodes.push(Node::new(key, value, NULL_NODE, NULL_NODE));
            (0, None)
        } else {
            let (root, order) = Node::splay(&mut self.nodes, self.root, &key);
            match order {
                Ordering::Equal => {
                    let old = mem::replace(&mut self.nodes[root as usize].val, value);
                    (root, Some(old))
                }
                Ordering::Less => {
                    let lft = mem::replace(&mut self.nodes[root as usize].lft, NULL_NODE);
                    self.nodes.push(Node::new(key, value, lft, root));
                    (self.nodes.len() as NodeIndex - 1, None)
                }
                Ordering::Greater => {
                    let rgt = mem::replace(&mut self.nodes[root as usize].rgt, NULL_NODE);
                    self.nodes.push(Node::new(key, value, root, rgt));
                    (self.nodes.len() as NodeIndex - 1, None)
                }
            }

        };
        assert!(new_root != NULL_NODE);

        self.root = new_root;
        old_value
    }
    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
        where K: Borrow<Q>,
              Q: Ord
    {
        self.contains_key(key).as_option().map(|_| self.non_empty_pop_root().1)
    }
    pub fn pop_last(&mut self) -> Option<(K, V)> {
        (!self.nodes.is_empty()).as_option().map(|_| {
            let key = &self.nodes.last().unwrap().key as *const _;
            self.contains_key(unsafe { &*key });
            self.non_empty_pop_root()
        })
    }
    pub fn pop_root(&mut self) -> Option<(K, V)> {
        (!self.nodes.is_empty()).as_option().map(|_| self.non_empty_pop_root())
    }
    pub fn get_lftmost(&mut self) -> Option<(&K, &V)> {
        (!self.nodes.is_empty()).as_option().map(move |_| {
            self.root = Node::splay_lftmost(&mut self.nodes, self.root);
            let n = &self.nodes[self.root as usize];
            (&n.key, &n.val)
        })
    }
    pub fn take_lftmost(&mut self) -> Option<(K, V)> {
        (!self.nodes.is_empty()).as_option().map(|_| {
            self.root = Node::splay_lftmost(&mut self.nodes, self.root);
            self.non_empty_pop_root()
        })
    }
    fn non_empty_pop_root(&mut self) -> (K, V) {
        let (e, root) = Node::pop(&mut self.nodes, self.root);
        self.root = root;
        e
    }
}
impl<K, V> Tree<K, V> {
    pub fn iter(&self) -> iter::Iter<K, V> {
        iter::Iter::new(self)
    }
    pub fn root(&self) -> Option<NodeIndex> {
        (!self.nodes.is_empty()).as_option().map(|_| self.root)
    }
    pub fn root_ref(&self) -> Option<&Node<K, V>> {
        (!self.nodes.is_empty()).as_option().map(|_| &self.nodes[self.root as usize])
    }
    pub fn root_mut(&mut self) -> Option<&mut Node<K, V>> {
        (!self.nodes.is_empty()).as_option().map(move |_| &mut self.nodes[self.root as usize])
    }
    pub fn node_ref(&self, i: NodeIndex) -> &Node<K, V> {
        &self.nodes[i as usize]
    }
    pub fn node_mut(&mut self, i: NodeIndex) -> &mut Node<K, V> {
        &mut self.nodes[i as usize]
    }
    pub fn len(&self) -> usize {
        self.nodes.len()
    }
    pub fn capacity(&self) -> usize {
        self.nodes.capacity()
    }
}
impl<K, V> hash::Hash for Tree<K, V>
    where K: hash::Hash,
          V: hash::Hash
{
    fn hash<H>(&self, state: &mut H)
        where H: hash::Hasher
    {
        for (k, v) in self.iter() {
            k.hash(state);
            v.hash(state);
        }
    }
}
impl<K, V> PartialEq for Tree<K, V>
    where K: PartialEq,
          V: PartialEq
{
    fn eq(&self, other: &Self) -> bool {
        self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| a.eq(&b))
    }
}
impl<K, V> Eq for Tree<K, V>
    where K: Eq,
          V: Eq
{
}
impl<K, V> PartialOrd for Tree<K, V>
    where K: PartialOrd,
          V: PartialOrd
{
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        let mut i0 = self.iter();
        let mut i1 = other.iter();
        loop {
            match (i0.next(), i1.next()) {
                (None, None) => return Some(cmp::Ordering::Equal),
                (None, _) => return Some(cmp::Ordering::Less),
                (_, None) => return Some(cmp::Ordering::Greater),
                (Some(e0), Some(e1)) => {
                    match e0.partial_cmp(&e1) {
                        Some(cmp::Ordering::Equal) => {}
                        not_equal => return not_equal,
                    }
                }
            }
        }
    }
}
impl<K, V> Ord for Tree<K, V>
    where K: Ord,
          V: Ord
{
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        let mut i0 = self.iter();
        let mut i1 = other.iter();
        loop {
            match (i0.next(), i1.next()) {
                (None, None) => return cmp::Ordering::Equal,
                (None, _) => return cmp::Ordering::Less,
                (_, None) => return cmp::Ordering::Greater,
                (Some(e0), Some(e1)) => {
                    match e0.cmp(&e1) {
                        cmp::Ordering::Equal => {}
                        not_equal => return not_equal,
                    }
                }
            }
        }
    }
}

trait OptionLike {
    fn as_option(&self) -> Option<&Self>;
}
impl OptionLike for bool {
    fn as_option(&self) -> Option<&Self> {
        if *self {
            Some(self)
        } else {
            None
        }
    }
}
<commit_msg>Refactor splay_by function<commit_after>use std::u32;
use std::mem;
use std::cmp;
use std::hash;
use std::borrow::Borrow;
use std::cmp::Ordering;
use iter;

pub type NodeIndex = u32;
const NULL_NODE: NodeIndex = u32::MAX;

#[derive(Debug, Clone)]
pub struct Node<K, V> {
    pub lft: NodeIndex,
    pub rgt: NodeIndex,
    pub key: K,
    pub val: V,
}
impl<K, V> Node<K, V> {
    pub fn rgt(&self) -> Option<NodeIndex> {
        (self.rgt != NULL_NODE).as_option().map(|_| self.rgt)
    }
    pub fn lft(&self) -> Option<NodeIndex> {
        (self.lft != NULL_NODE).as_option().map(|_| self.lft)
    }
}
impl<K, V> Node<K, V>
    where K: Ord
{
    fn new(key: K, value: V, lft: NodeIndex, rgt: NodeIndex) -> Self {
        Node {
            key: key,
            val: value,
            lft: lft,
            rgt: rgt,
        }
    }
    fn pop(nodes: &mut Vec<Self>, root: NodeIndex) -> ((K, V), NodeIndex) {
        let children = {
            let n = &mut nodes[root as usize];
            (mem::replace(&mut n.lft, NULL_NODE), mem::replace(&mut n.rgt, NULL_NODE))
        };
        let new_root = match children {
            (NULL_NODE, NULL_NODE) => NULL_NODE,
            (lft, NULL_NODE) => lft,
            (NULL_NODE, rgt) => rgt,
            (lft, mut rgt) => {
                let lft_rgt = mem::replace(&mut nodes[lft as usize].rgt, NULL_NODE);
                if lft_rgt != NULL_NODE {
                    rgt = Node::splay_lftmost(nodes, rgt);
                    nodes[rgt as usize].lft = lft_rgt;
                }
                nodes[lft as usize].rgt = rgt;
                lft
            }
        };
        if nodes.len() as NodeIndex - 1 != root {
            let key = &nodes[nodes.len() - 1].key as *const _;
            let _ = Node::splay(nodes, new_root, unsafe { &*key });
            let last = nodes.pop().unwrap();
            let old = mem::replace(&mut nodes[root as usize], last);
            ((old.key, old.val), root)
        } else {
            (nodes.pop().map(|n| (n.key, n.val)).unwrap(), new_root)
        }
    }
    fn splay<Q: ?Sized>(nodes: &mut [Self], root: NodeIndex, key: &Q) -> (NodeIndex, Ordering)
        where K: Borrow<Q>,
              Q: Ord
    {
        Node::splay_by(nodes, root, |k| key.cmp(k.borrow()))
    }
    fn splay_lftmost(nodes: &mut [Self], root: NodeIndex) -> NodeIndex {
        Node::splay_by(nodes, root, |_| Ordering::Less).0
    }
    fn splay_by<F>(nodes: &mut [Self], mut curr: NodeIndex, cmp: F) -> (NodeIndex, Ordering)
        where F: Fn(&K) -> Ordering
    {
        macro_rules! node{ ($index:expr) => { nodes[$index as usize] } };
        let mut lft_root = NULL_NODE;
        let mut rgt_root = NULL_NODE;
        let mut order = cmp(node!(curr).key.borrow());
        {
            let mut lft_rgtmost = &mut lft_root;
            let mut rgt_lftmost = &mut rgt_root;
            loop {
                let mut child;
                match order {
                    Ordering::Less if node!(curr).lft != NULL_NODE => {
                        // zig
                        child = mem::replace(&mut node!(curr).lft, NULL_NODE);
                        order = cmp(node!(child).key.borrow());
                        if Ordering::Less == order && node!(child).lft != NULL_NODE {
                            // zig-zig
                            let grand_child = mem::replace(&mut node!(child).lft, NULL_NODE);
                            node!(curr).lft = mem::replace(&mut node!(child).rgt, curr);
                            curr = mem::replace(&mut child, grand_child);
                            order = cmp(node!(child).key.borrow());
                        }
                        *rgt_lftmost = curr;
                        rgt_lftmost = unsafe { &mut *(&mut node!(curr).lft as *mut _) };
                    }
                    Ordering::Greater if node!(curr).rgt != NULL_NODE => {
                        // zag
                        child = mem::replace(&mut node!(curr).rgt, NULL_NODE);
                        order = cmp(node!(child).key.borrow());
                        if Ordering::Greater == order && node!(child).rgt != NULL_NODE {
                            // zag-zag
                            let grand_child = mem::replace(&mut node!(child).rgt, NULL_NODE);
                            node!(curr).rgt = mem::replace(&mut node!(child).lft, curr);
                            curr = mem::replace(&mut child, grand_child);
                            order = cmp(node!(child).key.borrow());
                        }
                        *lft_rgtmost = curr;
                        lft_rgtmost = unsafe { &mut *(&mut node!(curr).rgt as *mut _) };
                    }
                    _ => break,
                }
                curr = child;
            }
            *lft_rgtmost = mem::replace(&mut node!(curr).lft, NULL_NODE);
            *rgt_lftmost = mem::replace(&mut node!(curr).rgt, NULL_NODE);
        }
        node!(curr).lft = lft_root;
        node!(curr).rgt = rgt_root;
        (curr, order)
    }
}

#[derive(Debug, Clone)]
pub struct Tree<K, V> {
    root: NodeIndex,
    nodes: Vec<Node<K, V>>,
}
impl<K, V> Tree<K, V>
    where K: Ord
{
    pub fn new() -> Self {
        Tree {
            root: 0,
            nodes: Vec::new(),
        }
    }
    pub fn contains_key<Q: ?Sized>(&mut self, key: &Q) -> bool
        where K: Borrow<Q>,
              Q: Ord
    {
        if self.nodes.is_empty() {
            false
        } else {
            let (root, order) = Node::splay(&mut self.nodes, self.root, key);
            self.root = root;
            order == Ordering::Equal
        }
    }
    pub fn find_lower_bound<Q: ?Sized>(&mut self, key: &Q) -> Option<&K>
        where K: Borrow<Q>,
              Q: Ord
    {
        (!self.nodes.is_empty()).as_option().and_then(move |_| {
            let (root, order) = Node::splay(&mut self.nodes, self.root, key);
            self.root = root;
            if let Ordering::Greater = order {
                let mut root_rgt = self.nodes[self.root as usize].rgt;
                if root_rgt != NULL_NODE {
                    root_rgt = Node::splay_lftmost(&mut self.nodes, root_rgt);
                    self.nodes[self.root as usize].rgt = root_rgt;
                    Some(&self.nodes[root_rgt as usize].key)
                } else {
                    None
                }
            } else {
                Some(&self.nodes[self.root as usize].key)
            }
        })
    }
    pub fn find_upper_bound<Q: ?Sized>(&mut self, key: &Q) -> Option<&K>
        where K: Borrow<Q>,
              Q: Ord
    {
        (!self.nodes.is_empty()).as_option().and_then(move |_| {
            let (root, order) = Node::splay(&mut self.nodes, self.root, key);
            self.root = root;
            if let Ordering::Less = order {
                Some(&self.nodes[self.root as usize].key)
            } else {
                let mut root_rgt = self.nodes[self.root as usize].rgt;
                if root_rgt != NULL_NODE {
                    root_rgt = Node::splay_lftmost(&mut self.nodes, root_rgt);
                    self.nodes[self.root as usize].rgt = root_rgt;
                    Some(&self.nodes[root_rgt as usize].key)
                } else {
                    None
                }
            }
        })
    }
    pub fn get<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V>
        where K: Borrow<Q>,
              Q: Ord
    {
        self.contains_key(key).as_option().map(move |_| &mut self.nodes[self.root as usize].val)
    }
    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
        let (new_root, old_value) = if self.nodes.is_empty() {
            self.nodes.push(Node::new(key, value, NULL_NODE, NULL_NODE));
            (0, None)
        } else {
            let (root, order) = Node::splay(&mut self.nodes, self.root, &key);
            match order {
                Ordering::Equal => {
                    let old = mem::replace(&mut self.nodes[root as usize].val, value);
                    (root, Some(old))
                }
                Ordering::Less => {
                    let lft = mem::replace(&mut self.nodes[root as usize].lft, NULL_NODE);
                    self.nodes.push(Node::new(key, value, lft, root));
                    (self.nodes.len() as NodeIndex - 1, None)
                }
                Ordering::Greater => {
                    let rgt = mem::replace(&mut self.nodes[root as usize].rgt, NULL_NODE);
                    self.nodes.push(Node::new(key, value, root, rgt));
                    (self.nodes.len() as NodeIndex - 1, None)
                }
            }
        };
        self.root = new_root;
        old_value
    }
    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
        where K: Borrow<Q>,
              Q: Ord
    {
        self.contains_key(key).as_option().map(|_| self.non_empty_pop_root().1)
    }
    pub fn pop_last(&mut self) -> Option<(K, V)> {
        (!self.nodes.is_empty()).as_option().map(|_| {
            let key = &self.nodes.last().unwrap().key as *const _;
            self.contains_key(unsafe { &*key });
            self.non_empty_pop_root()
        })
    }
    pub fn pop_root(&mut self) -> Option<(K, V)> {
        (!self.nodes.is_empty()).as_option().map(|_| self.non_empty_pop_root())
    }
    pub fn get_lftmost(&mut self) -> Option<(&K, &V)> {
        (!self.nodes.is_empty()).as_option().map(move |_| {
            self.root = Node::splay_lftmost(&mut self.nodes, self.root);
            let n = &self.nodes[self.root as usize];
            (&n.key, &n.val)
        })
    }
    pub fn take_lftmost(&mut self) -> Option<(K, V)> {
        (!self.nodes.is_empty()).as_option().map(|_| {
            self.root = Node::splay_lftmost(&mut self.nodes, self.root);
            self.non_empty_pop_root()
        })
    }
    fn non_empty_pop_root(&mut self) -> (K, V) {
        let (e, root) = Node::pop(&mut self.nodes, self.root);
        self.root = root;
        e
    }
}
impl<K, V> Tree<K, V> {
    pub fn iter(&self) -> iter::Iter<K, V> {
        iter::Iter::new(self)
    }
    pub fn root(&self) -> Option<NodeIndex> {
        (!self.nodes.is_empty()).as_option().map(|_| self.root)
    }
    pub fn root_ref(&self) -> Option<&Node<K, V>> {
        (!self.nodes.is_empty()).as_option().map(|_| &self.nodes[self.root as usize])
    }
    pub fn root_mut(&mut self) -> Option<&mut Node<K, V>> {
        (!self.nodes.is_empty()).as_option().map(move |_| &mut self.nodes[self.root as usize])
    }
    pub fn node_ref(&self, i: NodeIndex) -> &Node<K, V> {
        &self.nodes[i as usize]
    }
    pub fn node_mut(&mut self, i: NodeIndex) -> &mut Node<K, V> {
        &mut self.nodes[i as usize]
    }
    pub fn len(&self) -> usize {
        self.nodes.len()
    }
    pub fn capacity(&self) -> usize {
        self.nodes.capacity()
    }
}
impl<K, V> hash::Hash for Tree<K, V>
    where K: hash::Hash,
          V: hash::Hash
{
    fn hash<H>(&self, state: &mut H)
        where H: hash::Hasher
    {
        for (k, v) in self.iter() {
            k.hash(state);
            v.hash(state);
        }
    }
}
impl<K, V> PartialEq for Tree<K, V>
    where K: PartialEq,
          V: PartialEq
{
    fn eq(&self, other: &Self) -> bool {
        self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| a.eq(&b))
    }
}
impl<K, V> Eq for Tree<K, V>
    where K: Eq,
          V: Eq
{
}
impl<K, V> PartialOrd for Tree<K, V>
    where K: PartialOrd,
          V: PartialOrd
{
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        let mut i0 = self.iter();
        let mut i1 = other.iter();
        loop {
            match (i0.next(), i1.next()) {
                (None, None) => return Some(cmp::Ordering::Equal),
                (None, _) => return Some(cmp::Ordering::Less),
                (_, None) => return Some(cmp::Ordering::Greater),
                (Some(e0), Some(e1)) => {
                    match e0.partial_cmp(&e1) {
                        Some(cmp::Ordering::Equal) => {}
                        not_equal => return not_equal,
                    }
                }
            }
        }
    }
}
impl<K, V> Ord for Tree<K, V>
    where K: Ord,
          V: Ord
{
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        let mut i0 = self.iter();
        let mut i1 = other.iter();
        loop {
            match (i0.next(), i1.next()) {
                (None, None) => return cmp::Ordering::Equal,
                (None, _) => return cmp::Ordering::Less,
                (_, None) => return cmp::Ordering::Greater,
                (Some(e0), Some(e1)) => {
                    match e0.cmp(&e1) {
                        cmp::Ordering::Equal => {}
                        not_equal => return not_equal,
                    }
                }
            }
        }
    }
}

trait OptionLike {
    fn as_option(&self) -> Option<&Self>;
}
impl OptionLike for bool {
    fn as_option(&self) -> Option<&Self> {
        if *self {
            Some(self)
        } else {
            None
        }
    }
}
<|endoftext|>


<commit_before>#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RoomType {
    BasicRoom,
    Coridor,
    Cave,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Room {
    pub room_type: RoomType,
    pub x: u32,
    pub y: u32,
    pub width: u32,
    pub height: u32,
}

pub type Rectangle = [u32; 4];

pub trait DungeonGenerator {
    fn generate(&mut self, seed: &[usize], width: u32, height: u32) -> Vec<Room>;
}

impl Room {
    pub fn new(room_type: RoomType, rect: Rectangle) -> Room {
        Room {
            room_type: room_type,
            x: rect[0],
            y: rect[1],
            width: rect[2],
            height: rect[3],
        }
    }
}
<commit_msg>add docs<commit_after>/// Type of the room
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RoomType {
    /// Basic room is the room where you'd better to plase enemies, treasures, bosses, etc
    BasicRoom,
    /// Coridor is a connecter Cave-BasicRoom or BasicRoom-BasicRoom
    Coridor,
    /// Cave is "main hall" of a dungeon, may not present in some generator type such as BSP
    Cave,
}

/// Room description struct
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Room {
    /// The type of the room
    pub room_type: RoomType,
    /// x absolute coordinate
    pub x: u32,
    /// y absolute coordinate
    pub y: u32,
    /// width of the room in units
    pub width: u32,
    /// height of the room in units
    pub height: u32,
}

pub type Rectangle = [u32; 4];

pub trait DungeonGenerator {
    /// width and height should be passed in units (for example tile size), not in pixels
    fn generate(&mut self, seed: &[usize], width: u32, height: u32) -> Vec<Room>;
}

impl Room {
    pub fn new(room_type: RoomType, rect: Rectangle) -> Room {
        Room {
            room_type: room_type,
            x: rect[0],
            y: rect[1],
            width: rect[2],
            height: rect[3],
        }
    }
}
<|endoftext|>


<commit_before>use libc::*;
use std::ffi::{CStr, CString};
use std::str::FromStr;

use engine::Engine;
use errors::*;

include!(concat!(env!("OUT_DIR"), "/cvar_array.rs"));

pub const EMPTY_CVAR_T: cvar_t = cvar_t {
    name: 0 as *const _,
    string: 0 as *mut _,
    flags: 0,
    value: 0f32,
    next: 0 as *mut _,
};

#[repr(C)]
pub struct cvar_t {
    pub name: *const c_char,
    pub string: *mut c_char,
    flags: c_int,
    value: c_float,
    next: *mut cvar_t,
}

pub struct CVar {
    engine_cvar: *mut cvar_t,
    default_value: &'static str,
    name: &'static str,
}

impl CVar {
    /// Creates a new CVar instance.
    pub fn new(engine_cvar: &mut cvar_t, name: &'static str, default_value: &'static str) -> Self {
        Self {
            engine_cvar,
            default_value,
            name,
        }
    }

    /// Retrieves a reference to the engine CVar.
    ///
    /// # Safety
    /// Unsafe because this function should only be called from the main game thread.
    /// You should also ensure that you don't call any engine functions while holding
    /// this reference, because the game also has a mutable reference to this CVar.
    pub unsafe fn get_engine_cvar(&self) -> Result<&cvar_t> {
        ensure!(!self.engine_cvar.is_null(), "engine_cvar is null");

        Ok(&*self.engine_cvar)
    }

    /// Retrieves a mutable reference to the engine CVar.
    ///
    /// # Safety
    /// Unsafe because this function should only be called from the main game thread.
    /// You should also ensure that you don't call any engine functions while holding
    /// this reference, because the game also has a mutable reference to this CVar.
    pub unsafe fn get_engine_cvar_mut(&self) -> Result<&mut cvar_t> {
        ensure!(!self.engine_cvar.is_null(), "engine_cvar is null");

        Ok(&mut *self.engine_cvar)
    }

    /// Registers this console variable.
    pub fn register(&self, engine: &Engine) -> Result<()> {
        let ptr = {
            let engine_cvar = unsafe { self.get_engine_cvar_mut()? };

            if engine_cvar.name.is_null() {
                let name_cstring = CString::new(self.name)
                    .chain_err(|| "could not convert CVar name to CString")?;

                // HACK: leak name_cstring.
                engine_cvar.name = name_cstring.into_raw();
            }

            // This CString needs to be valid only for the duration of Cvar_RegisterVariable().
            let default_value_cstring = CString::new(self.default_value)
                .chain_err(|| "could not convert CVar name to CString")?;

            let ptr = default_value_cstring.into_raw();
            engine_cvar.string = ptr;
            ptr
        };

        engine.register_variable(self).chain_err(|| "could not register the variable")?;

        // Free that CString from above.
        unsafe { CString::from_raw(ptr) };

        Ok(())
    }

    /// Returns the string this variable is set to.
    ///
    /// # Safety
    /// Unsafe because this function should only be called from the main game thread.
    pub unsafe fn to_string(&self) -> Result<String> {
        let engine_cvar = self.get_engine_cvar()?;
        ensure!(!engine_cvar.string.is_null(), "the CVar string pointer was null");

        Ok(CStr::from_ptr(engine_cvar.string).to_string_lossy().into_owned())
    }

    /// Tries parsing this variable's value to the desired type.
    ///
    /// # Safety
    /// Unsafe because this function should only be called from the main game thread.
    pub unsafe fn parse<T>(&self) -> Result<T>
        where T: FromStr,
              <T as FromStr>::Err: ::std::error::Error + Send + 'static {
        let string = self.to_string()
            .chain_err(|| "could not get this CVar's string value")?;
        string.parse()
            .chain_err(|| "could not convert the CVar string to the desired type")
    }
}
<commit_msg>Don't leak CString while making the CVar name<commit_after>use libc::*;
use std::ffi::{CStr, CString};
use std::str::FromStr;

use engine::Engine;
use errors::*;

include!(concat!(env!("OUT_DIR"), "/cvar_array.rs"));

pub const EMPTY_CVAR_T: cvar_t = cvar_t {
    name: 0 as *const _,
    string: 0 as *mut _,
    flags: 0,
    value: 0f32,
    next: 0 as *mut _,
};

#[repr(C)]
pub struct cvar_t {
    pub name: *const c_char,
    pub string: *mut c_char,
    flags: c_int,
    value: c_float,
    next: *mut cvar_t,
}

pub struct CVar {
    engine_cvar: *mut cvar_t,
    default_value: &'static str,
    name_cstring: CString,
}

impl CVar {
    /// Creates a new CVar instance.
    pub fn new(engine_cvar: &mut cvar_t, name: &'static str, default_value: &'static str) -> Self {
        let cvar = Self {
            engine_cvar,
            default_value,
            name_cstring: CString::new(name).expect("could not convert the CVar name to CString")
        };

        engine_cvar.name = cvar.name_cstring.as_ptr();

        cvar
    }

    /// Retrieves a reference to the engine CVar.
    ///
    /// # Safety
    /// Unsafe because this function should only be called from the main game thread.
    /// You should also ensure that you don't call any engine functions while holding
    /// this reference, because the game also has a mutable reference to this CVar.
    pub unsafe fn get_engine_cvar(&self) -> Result<&cvar_t> {
        ensure!(!self.engine_cvar.is_null(), "engine_cvar is null");

        Ok(&*self.engine_cvar)
    }

    /// Retrieves a mutable reference to the engine CVar.
    ///
    /// # Safety
    /// Unsafe because this function should only be called from the main game thread.
    /// You should also ensure that you don't call any engine functions while holding
    /// this reference, because the game also has a mutable reference to this CVar.
    pub unsafe fn get_engine_cvar_mut(&self) -> Result<&mut cvar_t> {
        ensure!(!self.engine_cvar.is_null(), "engine_cvar is null");

        Ok(&mut *self.engine_cvar)
    }

    /// Registers this console variable.
    pub fn register(&self, engine: &Engine) -> Result<()> {
        let ptr = {
            let engine_cvar = unsafe { self.get_engine_cvar_mut()? };

            // This CString needs to be valid only for the duration of Cvar_RegisterVariable().
            let default_value_cstring = CString::new(self.default_value)
                .chain_err(|| "could not convert CVar name to CString")?;

            let ptr = default_value_cstring.into_raw();
            engine_cvar.string = ptr;
            ptr
        };

        engine.register_variable(self).chain_err(|| "could not register the variable")?;

        // Free that CString from above.
        unsafe { CString::from_raw(ptr) };

        Ok(())
    }

    /// Returns the string this variable is set to.
    ///
    /// # Safety
    /// Unsafe because this function should only be called from the main game thread.
    pub unsafe fn to_string(&self) -> Result<String> {
        let engine_cvar = self.get_engine_cvar()?;
        ensure!(!engine_cvar.string.is_null(), "the CVar string pointer was null");

        Ok(CStr::from_ptr(engine_cvar.string).to_string_lossy().into_owned())
    }

    /// Tries parsing this variable's value to the desired type.
    ///
    /// # Safety
    /// Unsafe because this function should only be called from the main game thread.
    pub unsafe fn parse<T>(&self) -> Result<T>
        where T: FromStr,
              <T as FromStr>::Err: ::std::error::Error + Send + 'static {
        let string = self.to_string()
            .chain_err(|| "could not get this CVar's string value")?;
        string.parse()
            .chain_err(|| "could not convert the CVar string to the desired type")
    }
}
<|endoftext|>


<commit_before>use std::mem;

pub trait Flat: Sized {
    type Element;

    fn new() -> Self;
    fn with_capacity(capacity: usize) -> Self;

    fn swap_remove(&mut self, index: usize) -> Option<Self::Element>;
    fn replace(&mut self,
               index: usize,
               element: Self::Element)
               -> Result<Self::Element, Self::Element>;

    fn push(&mut self, element: Self::Element);
}

pub trait FlatGet {
    type ElementRef;
    fn flat_get(self, index: usize) -> Option<Self::ElementRef>;
}

pub trait FlatGetMut {
    type ElementRefMut;
    fn flat_get_mut(self, index: usize) -> Option<Self::ElementRefMut>;
}

pub trait FlatAccess {
    type Access;
    fn flat_access(self) -> Self::Access;
}

pub trait FlatAccessMut {
    type AccessMut;
    fn flat_access_mut(self) -> Self::AccessMut;
}

impl<T> Flat for Vec<T> {
    type Element = T;

    #[inline]
    fn new() -> Self {
        Vec::new()
    }

    #[inline]
    fn with_capacity(capacity: usize) -> Self {
        Vec::with_capacity(capacity)
    }

    #[inline]
    fn replace(&mut self,
               index: usize,
               element: Self::Element)
               -> Result<Self::Element, Self::Element> {
        match self.get_mut(index) {
            Some(old) => Ok(mem::replace(old, element)),
            None => Err(element),
        }
    }

    #[inline]
    fn swap_remove(&mut self, index: usize) -> Option<Self::Element> {
        let index = index;
        if index < self.len() {
            Some(self.swap_remove(index))
        } else {
            None
        }
    }

    #[inline]
    fn push(&mut self, element: Self::Element) {
        self.push(element);
    }
}

impl<'a, T> FlatGet for &'a Vec<T> {
    type ElementRef = &'a T;

    fn flat_get(self, index: usize) -> Option<Self::ElementRef> {
        self.get(index)
    }
}

impl<'a, T> FlatGetMut for &'a mut Vec<T> {
    type ElementRefMut = &'a mut T;

    fn flat_get_mut(self, index: usize) -> Option<Self::ElementRefMut> {
        self.get_mut(index)
    }
}

impl<'a, T> FlatAccess for &'a Vec<T> {
    type Access = &'a [T];

    fn flat_access(self) -> Self::Access {
        &self[..]
    }
}

impl<'a, T> FlatAccessMut for &'a mut Vec<T> {
    type AccessMut = &'a mut [T];

    fn flat_access_mut(self) -> Self::AccessMut {
        &mut self[..]
    }
}

#[macro_export]
macro_rules! define_flat {
    (
        #[element($element:ident, & $element_ref:ident, &mut $element_ref_mut:ident)]
        #[access(& $access:ident, &mut $access_mut:ident)]
        pub struct $struct_name:ident {
            $(#[element($element_field:ident)]
              pub $field:ident : Vec<$field_type:ty>,)+
        }
    ) => {
        pub struct $struct_name {
            pub $($field : Vec<$field_type>,)+
        }

        pub struct $element {
            pub $($element_field : $field_type,)+
        }

        pub struct $element_ref <'a> {
            pub $($element_field : &'a $field_type,)+
        }

        pub struct $element_ref_mut <'a> {
            pub $($element_field : &'a mut $field_type,)+
        }

        pub struct $access <'a> {
            pub $($field : &'a [$field_type],)+
        }

        pub struct $access_mut <'a> {
            pub $($field : &'a mut [$field_type],)+
        }

        impl $crate::Flat for $struct_name {
            type Element = $element;

            #[inline]
            fn new() -> Self {
                $struct_name {
                    $($field : $crate::Flat::new()),+
                }
            }

            #[inline]
            fn with_capacity(capacity: usize) -> Self {
                $struct_name {
                    $($field : $crate::Flat::with_capacity(capacity)),+
                }
            }

            #[inline]
            fn replace(&mut self,
                       index: usize,
                       element: Self::Element)
                       -> Result<Self::Element, Self::Element> {
                match ($($crate::Flat::replace(&mut self.$field,
                                               index,
                                               element.$element_field),)+) {
                    ($(Ok($element_field),)+) => Ok($element {
                        $($element_field: $element_field,)+
                    }),
                    ($(Err($element_field),)+) => Err($element {
                        $($element_field: $element_field,)+
                    }),
                    _ => panic!("out of lockstep derived flat in `replace`"),
                }
            }

            #[inline]
            fn swap_remove(&mut self, index: usize) -> Option<Self::Element> {
                match ($($crate::Flat::swap_remove(&mut self.$field, index),)+) {
                    ($(Some($element_field),)+) => Some($element {
                        $($element_field: $element_field,)+
                    }),
                    ($($element_field@None,)+) => None,
                    _ => panic!("out of lockstep derived flat in `swap_remove`"),
                }
            }

            #[inline]
            fn push(&mut self, element: Self::Element) {
                $($crate::Flat::push(&mut self.$field, element.$element_field);)+
            }
        }

        impl<'a> FlatGet for &'a $struct_name {
            type ElementRef = $element_ref <'a>;

            fn flat_get(self, index: usize) -> Option<Self::ElementRef> {
                match ($($crate::FlatGet::flat_get(&self.$field, index),)+) {
                    ($(Some($element_field),)+) => Some($element_ref {
                        $($element_field: $element_field,)+
                    }),
                    ($($element_field@None,)+) => None,
                    _ => panic!("out of lockstep derived flat in `flat_get`"),
                }
            }
        }

        impl<'a> FlatGetMut for &'a mut $struct_name {
            type ElementRefMut = $element_ref_mut <'a>;

            fn flat_get_mut(self, index: usize) -> Option<Self::ElementRefMut> {
                match ($($crate::FlatGetMut::flat_get_mut(&mut self.$field, index),)+) {
                    ($(Some($element_field),)+) => Some($element_ref_mut {
                        $($element_field: $element_field,)+
                    }),
                    ($($element_field@None,)+) => None,
                    _ => panic!("out of lockstep derived flat in `flat_get_mut`"),
                }
            }
        }

        impl<'a> FlatAccess for &'a $struct_name {
            type Access = $access <'a>;

            fn flat_access(self) -> Self::Access {
                $access {
                    $($field: $crate::FlatAccess::flat_access(&self.$field),)+
                }
            }
        }

        impl<'a> FlatAccessMut for &'a mut $struct_name {
            type AccessMut = $access_mut <'a>;

            fn flat_access_mut(self) -> Self::AccessMut {
                $access_mut {
                    $($field: $crate::FlatAccessMut::flat_access_mut(&mut self.$field),)+
                }
            }
        }
    }
}
<commit_msg>generalise derive_flat away from Vec<commit_after>use std::mem;

pub trait Flat: Sized {
    type Element;

    fn new() -> Self;
    fn with_capacity(capacity: usize) -> Self;

    fn swap_remove(&mut self, index: usize) -> Option<Self::Element>;
    fn replace(&mut self,
               index: usize,
               element: Self::Element)
               -> Result<Self::Element, Self::Element>;

    fn push(&mut self, element: Self::Element);
}

pub trait FlatGet {
    type ElementRef;
    fn flat_get(self, index: usize) -> Option<Self::ElementRef>;
}

pub trait FlatGetMut {
    type ElementRefMut;
    fn flat_get_mut(self, index: usize) -> Option<Self::ElementRefMut>;
}

pub trait FlatAccess {
    type Access;
    fn flat_access(self) -> Self::Access;
}

pub trait FlatAccessMut {
    type AccessMut;
    fn flat_access_mut(self) -> Self::AccessMut;
}

impl<T> Flat for Vec<T> {
    type Element = T;

    #[inline]
    fn new() -> Self {
        Vec::new()
    }

    #[inline]
    fn with_capacity(capacity: usize) -> Self {
        Vec::with_capacity(capacity)
    }

    #[inline]
    fn replace(&mut self,
               index: usize,
               element: Self::Element)
               -> Result<Self::Element, Self::Element> {
        match self.get_mut(index) {
            Some(old) => Ok(mem::replace(old, element)),
            None => Err(element),
        }
    }

    #[inline]
    fn swap_remove(&mut self, index: usize) -> Option<Self::Element> {
        let index = index;
        if index < self.len() {
            Some(self.swap_remove(index))
        } else {
            None
        }
    }

    #[inline]
    fn push(&mut self, element: Self::Element) {
        self.push(element);
    }
}

impl<'a, T> FlatGet for &'a Vec<T> {
    type ElementRef = &'a T;

    fn flat_get(self, index: usize) -> Option<Self::ElementRef> {
        self.get(index)
    }
}

impl<'a, T> FlatGetMut for &'a mut Vec<T> {
    type ElementRefMut = &'a mut T;

    fn flat_get_mut(self, index: usize) -> Option<Self::ElementRefMut> {
        self.get_mut(index)
    }
}

impl<'a, T> FlatAccess for &'a Vec<T> {
    type Access = &'a [T];

    fn flat_access(self) -> Self::Access {
        &self[..]
    }
}

impl<'a, T> FlatAccessMut for &'a mut Vec<T> {
    type AccessMut = &'a mut [T];

    fn flat_access_mut(self) -> Self::AccessMut {
        &mut self[..]
    }
}

#[macro_export]
macro_rules! derive_flat {
    (
        #[element($element:ident, & $element_ref:ident, &mut $element_ref_mut:ident)]
        #[access(& $access:ident, &mut $access_mut:ident)]
        pub struct $struct_name:ident {
            $(#[element($element_field:ident)]
              pub $field:ident : $field_type:ty,)+
        }
    ) => {
        pub struct $struct_name {
            pub $($field : $field_type,)+
        }

        pub struct $element {
            pub $($element_field : <$field_type as $crate::Flat>::Element,)+
        }

        pub struct $element_ref <'a> {
            pub $($element_field : <&'a $field_type as $crate::FlatGet>::ElementRef,)+
        }

        pub struct $element_ref_mut <'a> {
            pub $($element_field : <&'a mut $field_type as $crate::FlatGetMut>::ElementRefMut,)+
        }

        pub struct $access <'a> {
            pub $($field : <&'a $field_type as $crate::FlatAccess>::Access,)+
        }

        pub struct $access_mut <'a> {
            pub $($field : <&'a mut $field_type as $crate::FlatAccessMut>::AccessMut,)+
        }

        impl $crate::Flat for $struct_name {
            type Element = $element;

            #[inline]
            fn new() -> Self {
                $struct_name {
                    $($field : $crate::Flat::new()),+
                }
            }

            #[inline]
            fn with_capacity(capacity: usize) -> Self {
                $struct_name {
                    $($field : $crate::Flat::with_capacity(capacity)),+
                }
            }

            #[inline]
            fn replace(&mut self,
                       index: usize,
                       element: Self::Element)
                       -> Result<Self::Element, Self::Element> {
                match ($($crate::Flat::replace(&mut self.$field,
                                               index,
                                               element.$element_field),)+) {
                    ($(Ok($element_field),)+) => Ok($element {
                        $($element_field: $element_field,)+
                    }),
                    ($(Err($element_field),)+) => Err($element {
                        $($element_field: $element_field,)+
                    }),
                    _ => panic!("out of lockstep derived flat in `replace`"),
                }
            }

            #[inline]
            fn swap_remove(&mut self, index: usize) -> Option<Self::Element> {
                match ($($crate::Flat::swap_remove(&mut self.$field, index),)+) {
                    ($(Some($element_field),)+) => Some($element {
                        $($element_field: $element_field,)+
                    }),
                    ($($element_field@None,)+) => None,
                    _ => panic!("out of lockstep derived flat in `swap_remove`"),
                }
            }

            #[inline]
            fn push(&mut self, element: Self::Element) {
                $($crate::Flat::push(&mut self.$field, element.$element_field);)+
            }
        }

        impl<'a> FlatGet for &'a $struct_name {
            type ElementRef = $element_ref <'a>;

            fn flat_get(self, index: usize) -> Option<Self::ElementRef> {
                match ($($crate::FlatGet::flat_get(&self.$field, index),)+) {
                    ($(Some($element_field),)+) => Some($element_ref {
                        $($element_field: $element_field,)+
                    }),
                    ($($element_field@None,)+) => None,
                    _ => panic!("out of lockstep derived flat in `flat_get`"),
                }
            }
        }

        impl<'a> FlatGetMut for &'a mut $struct_name {
            type ElementRefMut = $element_ref_mut <'a>;

            fn flat_get_mut(self, index: usize) -> Option<Self::ElementRefMut> {
                match ($($crate::FlatGetMut::flat_get_mut(&mut self.$field, index),)+) {
                    ($(Some($element_field),)+) => Some($element_ref_mut {
                        $($element_field: $element_field,)+
                    }),
                    ($($element_field@None,)+) => None,
                    _ => panic!("out of lockstep derived flat in `flat_get_mut`"),
                }
            }
        }

        impl<'a> FlatAccess for &'a $struct_name {
            type Access = $access <'a>;

            fn flat_access(self) -> Self::Access {
                $access {
                    $($field: $crate::FlatAccess::flat_access(&self.$field),)+
                }
            }
        }

        impl<'a> FlatAccessMut for &'a mut $struct_name {
            type AccessMut = $access_mut <'a>;

            fn flat_access_mut(self) -> Self::AccessMut {
                $access_mut {
                    $($field: $crate::FlatAccessMut::flat_access_mut(&mut self.$field),)+
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use piston_window::*;
use piston_window::types::Color;

use board::Board;
use tetromino::*;
use settings::*;

enum GameState {
    Playing,
    Paused
}

pub trait Game {
    fn on_input(&mut self, input: Input);
    fn on_update(&mut self, update_args: UpdateArgs);
    fn on_render(&mut self, render_args: RenderArgs, e: PistonWindow);
}

pub trait Renderer {
    fn render(&self, context: Context, graphics: &mut G2d);
}

pub trait GridRenderer {
    fn render(&self, x: i32, y: i32, context: Context, graphics: &mut G2d);
}

pub struct Rustris {
    board: Board,
    current_piece: Piece,
    next_piece: Piece,
    score: u32,
    level: u32,
    // state: GameState
}
impl Rustris {
    pub fn new() -> Rustris {
        Rustris {
            board: Board::new(),
            current_piece: create_random_piece(),
            next_piece: create_random_piece(),
            score: 0,
            level: 1
        }
    }

    pub fn reset(&mut self) {

    }

    fn is_valid_board_position(&self, piece: &Piece) -> bool {
        piece.blocks_iter().all(|block| {
            (block.x >= 0 && block.x < WIDTH_IN_BLOCKS as i32 &&
             block.y >= 0 && block.y < HEIGHT_IN_BLOCKS as i32)
        })
    }
}
impl Game for Rustris {
    fn on_input(&mut self, input: Input) {
        let mut new_piece: Option<Piece> = None;
        match input {
            Input::Press(key) => {
                match key {
                    Button::Keyboard(Key::Up) => {
                        new_piece = Some(self.current_piece.rotated());
                    }
                    Button::Keyboard(Key::Down) => {

                    }
                    Button::Keyboard(Key::Left) => {
                        new_piece = Some(self.current_piece.moved(Direction::Left));
                    }
                    Button::Keyboard(Key::Right) => {
                        new_piece = Some(self.current_piece.moved(Direction::Right));
                    }
                    Button::Keyboard(Key::Space) => {

                    }
                    _ => {}
                }
            }
            _ => {}
        }
        match new_piece {
            Some(p) => {
                if self.is_valid_board_position(&p) {
                    self.current_piece = p
                }
            },
            None => {}
        }
    }

    fn on_update(&mut self, update_args: UpdateArgs) {

    }

    fn on_render(&mut self, render_args: RenderArgs, e: PistonWindow) {
        e.draw_2d(|c, g| {
            clear([0.0, 0.0, 0.0, 1.0], g);
            self.board.render(c, g);
            self.current_piece.render(c, g);
        });
    }
}

pub fn render_square_in_grid(x: i32, y: i32, color: Color, context: Context, graphics: &mut G2d) {
    let square = rectangle::square(
        0.0, 0.0, BLOCK_SIZE - (2.0 * GRID_LINE_WIDTH)
    );
    let transform = context.transform
        // Translate the origin of the transform based on where the grid starts
        .trans(GRID_X_OFFSET, GRID_Y_OFFSET)
        // Translate the square into the first grid cell (off of the bounding box)
        .trans(GRID_LINE_WIDTH, GRID_LINE_WIDTH)
        // Translate the square into the proper grid cell based on the grid x and y position
        .trans((x as f64)*BLOCK_SIZE, (y as f64)*BLOCK_SIZE);
    rectangle(color, square, transform, graphics);
}

// pub struct TheGame {
//     rotation: f64,
//     x: f64,
//     y: f64,
//     up_d: bool, down_d: bool, left_d: bool, right_d: bool
// }
// impl TheGame {
//     pub fn new() -> TheGame {
//         TheGame { rotation : 0.0, x : 0.0, y : 0.0, up_d: false, down_d: false, left_d: false, right_d: false }
//     }
// }
// impl Game for TheGame {
//     fn on_update(&mut self, update_args: UpdateArgs) {
//         self.rotation += 3.0 * update_args.dt;
//         if self.up_d {
//             self.y += (-50.0) * update_args.dt;
//         }
//         if self.down_d {
//             self.y += (50.0) * update_args.dt;
//         }
//         if self.left_d {
//             self.x += (-50.0) * update_args.dt;
//         }
//         if self.right_d {
//             self.x += (50.0) * update_args.dt;
//         }
//     }
//     fn on_render(&mut self, render_args: RenderArgs, e: PistonWindow) {
//         e.draw_2d(|c, g| {
//             clear([0.0, 0.0, 0.0, 1.0], g);
//             let center = c.transform.trans((render_args.width / 2) as f64, (render_args.height / 2) as f64);
//             let square = rectangle::square(0.0, 0.0, 100.0);
//             let red = [1.0, 0.0, 0.0, 1.0];
//             rectangle(red, square, center.trans(self.x, self.y).rot_rad(self.rotation).trans(-50.0, -50.0), g);
//         });
//     }
//     fn on_input(&mut self, inp: Input) {
//         match inp {
//             Input::Press(but) => {
//                 match but {
//                     Button::Keyboard(Key::Up) => {
//                         self.up_d = true;
//                     }
//                     Button::Keyboard(Key::Down) => {
//                         self.down_d = true;
//                     }
//                     Button::Keyboard(Key::Left) => {
//                         self.left_d = true;
//                     }
//                     Button::Keyboard(Key::Right) => {
//                         self.right_d = true;
//                     }
//                     _ => {}
//                 }
//             }
//             Input::Release(but) => {
//                 match but {
//                     Button::Keyboard(Key::Up) => {
//                         self.up_d = false;
//                     }
//                     Button::Keyboard(Key::Down) => {
//                         self.down_d = false;
//                     }
//                     Button::Keyboard(Key::Left) => {
//                         self.left_d = false;
//                     }
//                     Button::Keyboard(Key::Right) => {
//                         self.right_d = false;
//                     }
//                     _ => {}
//                 }
//             }
//             _ => {}
//         }
//     }
// }
<commit_msg>clean up the code around handling the new piece by moving the validation into a set_current_piece method<commit_after>use piston_window::*;
use piston_window::types::Color;

use board::Board;
use tetromino::*;
use settings::*;

enum GameState {
    Playing,
    Paused
}

pub trait Game {
    fn on_input(&mut self, input: Input);
    fn on_update(&mut self, update_args: UpdateArgs);
    fn on_render(&mut self, render_args: RenderArgs, e: PistonWindow);
}

pub trait Renderer {
    fn render(&self, context: Context, graphics: &mut G2d);
}

pub trait GridRenderer {
    fn render(&self, x: i32, y: i32, context: Context, graphics: &mut G2d);
}

pub struct Rustris {
    board: Board,
    current_piece: Piece,
    next_piece: Piece,
    score: u32,
    level: u32,
    // state: GameState
}
impl Rustris {
    pub fn new() -> Rustris {
        Rustris {
            board: Board::new(),
            current_piece: create_random_piece(),
            next_piece: create_random_piece(),
            score: 0,
            level: 1
        }
    }

    pub fn reset(&mut self) {

    }

    pub fn set_current_piece(&mut self, piece: Piece) {
        if self.is_valid_board_position(&piece) {
            self.current_piece = piece;
        }
    }

    fn is_valid_board_position(&self, piece: &Piece) -> bool {
        piece.blocks_iter().all(|block| {
            (block.x >= 0 && block.x < WIDTH_IN_BLOCKS as i32 &&
             block.y >= 0 && block.y < HEIGHT_IN_BLOCKS as i32)
        })
    }
}
impl Game for Rustris {
    fn on_input(&mut self, input: Input) {
        match input {
            Input::Press(key) => {
                match key {
                    Button::Keyboard(Key::Up) => {
                        let rotated = self.current_piece.rotated();
                        self.set_current_piece(rotated);
                    }
                    Button::Keyboard(Key::Down) => {

                    }
                    Button::Keyboard(Key::Left) => {
                        let moved = self.current_piece.moved(Direction::Left);
                        self.set_current_piece(moved);
                    }
                    Button::Keyboard(Key::Right) => {
                        let moved = self.current_piece.moved(Direction::Right);
                        self.set_current_piece(moved);
                    }
                    Button::Keyboard(Key::Space) => {

                    }
                    _ => {}
                }
            }
            _ => {}
        }
    }

    fn on_update(&mut self, update_args: UpdateArgs) {

    }

    fn on_render(&mut self, render_args: RenderArgs, e: PistonWindow) {
        e.draw_2d(|c, g| {
            clear([0.0, 0.0, 0.0, 1.0], g);
            self.board.render(c, g);
            self.current_piece.render(c, g);
        });
    }
}

pub fn render_square_in_grid(x: i32, y: i32, color: Color, context: Context, graphics: &mut G2d) {
    let square = rectangle::square(
        0.0, 0.0, BLOCK_SIZE - (2.0 * GRID_LINE_WIDTH)
    );
    let transform = context.transform
        // Translate the origin of the transform based on where the grid starts
        .trans(GRID_X_OFFSET, GRID_Y_OFFSET)
        // Translate the square into the first grid cell (off of the bounding box)
        .trans(GRID_LINE_WIDTH, GRID_LINE_WIDTH)
        // Translate the square into the proper grid cell based on the grid x and y position
        .trans((x as f64)*BLOCK_SIZE, (y as f64)*BLOCK_SIZE);
    rectangle(color, square, transform, graphics);
}

// pub struct TheGame {
//     rotation: f64,
//     x: f64,
//     y: f64,
//     up_d: bool, down_d: bool, left_d: bool, right_d: bool
// }
// impl TheGame {
//     pub fn new() -> TheGame {
//         TheGame { rotation : 0.0, x : 0.0, y : 0.0, up_d: false, down_d: false, left_d: false, right_d: false }
//     }
// }
// impl Game for TheGame {
//     fn on_update(&mut self, update_args: UpdateArgs) {
//         self.rotation += 3.0 * update_args.dt;
//         if self.up_d {
//             self.y += (-50.0) * update_args.dt;
//         }
//         if self.down_d {
//             self.y += (50.0) * update_args.dt;
//         }
//         if self.left_d {
//             self.x += (-50.0) * update_args.dt;
//         }
//         if self.right_d {
//             self.x += (50.0) * update_args.dt;
//         }
//     }
//     fn on_render(&mut self, render_args: RenderArgs, e: PistonWindow) {
//         e.draw_2d(|c, g| {
//             clear([0.0, 0.0, 0.0, 1.0], g);
//             let center = c.transform.trans((render_args.width / 2) as f64, (render_args.height / 2) as f64);
//             let square = rectangle::square(0.0, 0.0, 100.0);
//             let red = [1.0, 0.0, 0.0, 1.0];
//             rectangle(red, square, center.trans(self.x, self.y).rot_rad(self.rotation).trans(-50.0, -50.0), g);
//         });
//     }
//     fn on_input(&mut self, inp: Input) {
//         match inp {
//             Input::Press(but) => {
//                 match but {
//                     Button::Keyboard(Key::Up) => {
//                         self.up_d = true;
//                     }
//                     Button::Keyboard(Key::Down) => {
//                         self.down_d = true;
//                     }
//                     Button::Keyboard(Key::Left) => {
//                         self.left_d = true;
//                     }
//                     Button::Keyboard(Key::Right) => {
//                         self.right_d = true;
//                     }
//                     _ => {}
//                 }
//             }
//             Input::Release(but) => {
//                 match but {
//                     Button::Keyboard(Key::Up) => {
//                         self.up_d = false;
//                     }
//                     Button::Keyboard(Key::Down) => {
//                         self.down_d = false;
//                     }
//                     Button::Keyboard(Key::Left) => {
//                         self.left_d = false;
//                     }
//                     Button::Keyboard(Key::Right) => {
//                         self.right_d = false;
//                     }
//                     _ => {}
//                 }
//             }
//             _ => {}
//         }
//     }
// }
<|endoftext|>


<commit_before>use field::{Field, Content};
use ui::UI;
use ui::EndMessage;
use piston_window::*;
use common::{ParamType, MoveDestination, GameEndState};
use chrono::{DateTime, UTC};

pub struct Game<'a> {
    field: Field,
    ui: UI<'a>,
    msg: EndMessage<'a>,
    glyphs: Glyphs,
    mouse_x: f64,
    mouse_y: f64,
    game_ended: bool,
    panel_width: u32,
    in_ui: bool,
    game_start : DateTime<UTC>,
    game_end : Option<DateTime<UTC>>,
}

impl<'a> Game<'a> {
    pub fn new(glyphs: Glyphs, width: u32, height: u32, mines: u32) -> Game<'a> {
        Game {
            field: Field::new(width, height, mines),
            ui: UI::new(width, height, mines),
            msg: EndMessage::new(),
            glyphs: glyphs,
            mouse_x: 0.0,
            mouse_y: 0.0,
            game_ended: false,
            panel_width: 350,
            in_ui: false,
            game_start: UTC::now(),
            game_end : None,
        }
    }

    pub fn render(&mut self, window: &PistonWindow) {
        window.draw_2d(|c, g| {
            clear([0.0, 0.0, 0.0, 1.0], g);
            let field_rect = self.get_field_rect(window);
            self.field.draw(c, g, field_rect, &mut self.glyphs);

            let ui_rect = self.get_ui_rect(window);
            let game_end = match self.game_end {
                Some(t) => t,
                None => UTC::now(),
            };

            self.ui.draw(c, g, ui_rect, &mut self.glyphs, self.field.total_mines(), self.field.count_marked(), game_end - self.game_start);

            let msg_rect = self.get_msg_rect(window);
            self.msg.draw(c, g, msg_rect, &mut self.glyphs);
        });
    }

    fn get_field_rect(&self, window: &PistonWindow) -> [u32; 4] {
        let mut w = window.size().width - self.panel_width;
        w = (w /self.field.get_width()) * self.field.get_width();
        let mut h = window.size().height;
        h = (h /self.field.get_height()) * self.field.get_height();
        [0, 0, w, h]
    }

    fn get_ui_rect(&self, window: &PistonWindow) -> [u32; 4] {
        let mut field_w = window.size().width - self.panel_width;
        field_w = (field_w /self.field.get_width()) * self.field.get_width();
        let w = window.size().width - field_w;
        let h = window.size().height;
        [field_w, 0, w, h]
    }

    fn get_msg_rect(&self, window: &PistonWindow) -> [u32; 4] {
        let w_w = window.size().width;
        let w_h = window.size().height;
        let (m_w, m_h) = EndMessage::size();

        [
            ( (w_w-m_w) / 2 ),
            ( (w_h-m_h) / 2 ),
            m_w,
            m_h
        ]
    }

    pub fn proc_key(&mut self, button: Button, window: &PistonWindow) {
        if self.in_ui {
            match button {
                Button::Keyboard(key) => {
                    match  key {
                        Key::H => {
                            match self.ui.proc_key(ParamType::Height) {
                                Some(h) => {
                                    self.in_ui = false;
                                    self.msg.hide();
                                    self.field.reinit_field(h, ParamType::Height);
                                }
                                _ => {}
                            }
                        },
                        Key::M => {
                            match self.ui.proc_key(ParamType::Mines) {
                                Some(m) => {
                                    self.in_ui = false;
                                    self.msg.hide();
                                    self.field.reinit_field(m, ParamType::Mines);
                                }
                                _ => {}
                            }
                        },
                        Key::W => {
                            match self.ui.proc_key(ParamType::Width) {
                                Some(w) => {
                                    self.in_ui = false;
                                    self.msg.hide();
                                    self.field.reinit_field(w, ParamType::Width);
                                }
                                _ => {}
                            }
                        },
                        Key::Up => self.ui.change_selected(MoveDestination::Up),
                        Key::Down => self.ui.change_selected(MoveDestination::Down),
                        Key::Left => self.ui.change_selected(MoveDestination::Left),
                        Key::Right => self.ui.change_selected(MoveDestination::Right),
                        _ => {}
                    }
                }
                _ => {}
            }
        } else {
            match button {
                Button::Keyboard(key) => {
                    match key {
                        Key::R => self.restart(),
                        Key::Up => self.field.move_selection(MoveDestination::Up),
                        Key::Down => self.field.move_selection(MoveDestination::Down),
                        Key::Left => self.field.move_selection(MoveDestination::Left),
                        Key::Right => self.field.move_selection(MoveDestination::Right),
                        Key::Space => {
                            let ind = self.field.get_selected_ind();
                            self.open_cell(ind);
                        },
                        Key::LCtrl | Key::RCtrl => {
                            let ind = self.field.get_selected_ind();
                            self.toggle_mark(ind);
                        }
                        Key::H => {
                            self.ui.proc_key(ParamType::Height);
                            self.in_ui = true;
                        },
                        Key::M =>{
                            self.ui.proc_key(ParamType::Mines);
                            self.in_ui = true;
                        },
                        Key::W => {
                            self.ui.proc_key(ParamType::Width);
                            self.in_ui = true;
                        },
                        _ => {}
                    }
                },
                Button::Mouse(btn) => {
                    let field_rect = self.get_field_rect(window);
                    let cell_w = field_rect[2] / self.field.get_width();
                    let cell_h = field_rect[3] / self.field.get_height();
                    let mouse_x = self.mouse_x.floor() as u32;
                    let mouse_y = self.mouse_y.floor() as u32;
                    if (mouse_x < field_rect[0]) || (mouse_x > field_rect[0] + field_rect[2]) ||
                       (mouse_y < field_rect[1]) || (mouse_y > field_rect[1] + field_rect[3]) {
                        return;
                    }
                    let x = (mouse_x - field_rect[0]) / cell_w;
                    let y = (mouse_y - field_rect[1]) / cell_h;
                    let w = self.field.get_width();
                    match btn {
                        MouseButton::Left => {
                            self.open_cell(x + y*w);
                        },
                        MouseButton::Right => {

                            self.toggle_mark(x + y*w);
                        },
                        _ => {}
                    }
                }
            }
        }
    }

    fn toggle_mark(&mut self, i: u32) {
        if self.game_ended || self.field.revealed(i) {
            return;
        }
        self.field.toggle_mark(i);
    }

    fn open_cell(&mut self, i: u32) {
        if self.game_ended {
            return;
        }

        if !self.field.revealed(i) {
            self.check_reveal(i);
        } else {
            self.reveal_neighborhood(i);
        }
    }

    fn reveal_neighborhood(&mut self, i: u32) {
        let cells_count_opt = {
            if let &Content::Number(cells_count) = self.field.get_content(i) {
                Some(cells_count)
            } else {
                None
            }
        };

        if let Some(cells_count) = cells_count_opt {
            if self.field.get_neighborhood_count(i) == cells_count {
                let on_left_edge = i % self.field.get_width() == 0;
                let on_right_edge = (i+1) % self.field.get_width() == 0;

                for rdelta in -1..2i32 {
                    for cdelta in -1..2i32 {
                        if on_left_edge && (cdelta == -1) {
                            continue;
                        }
                        if on_right_edge && (cdelta == 1) {
                            continue;
                        }
                        let tgt = (i as i32) + rdelta*(self.field.get_width() as i32) + cdelta;
                        if (tgt < 0) || (tgt >= self.field.get_size() as i32) {
                            continue;
                        }
                        self.check_reveal(tgt as u32);
                    }
                }
            }
        }
    }

    pub fn check_reveal(&mut self, i : u32) {
        if self.field.marked(i) {
            return;
        }
        match *self.field.reveal(i) {
            Content::Mine(_) => {
                self.field.reveal_all();
                self.game_ended = true;
                self.field.set_killer(i);
                self.game_end = Some(UTC::now());
                self.msg.show( GameEndState::Lose );
                println!("Game over :(");
            },
            Content::None => {
                self.field.chain_reveal(i);
                if self.field.is_victory() {
                    self.msg.show( GameEndState::Win );
                    println!("You win :)");
                    self.game_ended = true;
                    self.game_end = Some(UTC::now());
                }
            }
            Content::Number(_i) => {
                if self.field.is_victory() {
                    self.msg.show( GameEndState::Win );
                    println!("You win :)");
                    self.game_ended = true;
                    self.game_end = Some(UTC::now());
                }
            }
        }
    }

    pub fn mouse_move(&mut self, mouse_rel: [f64; 2]) {
        self.mouse_x = mouse_rel[0];
        self.mouse_y = mouse_rel[1];
    }

    fn restart(&mut self) {
        self.game_ended = false;
        self.msg.hide();
        self.field.restart();
    }
}
<commit_msg>missed some changes<commit_after>use field::{Field, Content};
use ui::UI;
use ui::EndMessage;
use piston_window::*;
use common::{ParamType, MoveDestination, GameEndState};
use chrono::{DateTime, UTC, Duration};

pub struct Game<'a> {
    field: Field,
    ui: UI<'a>,
    msg: EndMessage<'a>,
    glyphs: Glyphs,
    mouse_x: f64,
    mouse_y: f64,
    game_ended: bool,
    panel_width: u32,
    in_ui: bool,
    game_start : Option<DateTime<UTC>>,
    game_end : Option<DateTime<UTC>>,
}

impl<'a> Game<'a> {
    pub fn new(glyphs: Glyphs, width: u32, height: u32, mines: u32) -> Game<'a> {
        Game {
            field: Field::new(width, height, mines),
            ui: UI::new(width, height, mines),
            msg: EndMessage::new(),
            glyphs: glyphs,
            mouse_x: 0.0,
            mouse_y: 0.0,
            game_ended: false,
            panel_width: 350,
            in_ui: false,
            game_start: None,
            game_end : None,
        }
    }

    pub fn render(&mut self, window: &PistonWindow) {
        window.draw_2d(|c, g| {
            clear([0.0, 0.0, 0.0, 1.0], g);
            let field_rect = self.get_field_rect(window);
            self.field.draw(c, g, field_rect, &mut self.glyphs);

            let ui_rect = self.get_ui_rect(window);

            let dur = match self.game_start {
                Some(game_start) => match self.game_end {
                    Some(game_end) => game_end - game_start,
                    None => UTC::now() - game_start,
                },
                None => Duration::seconds(0),
            };

            self.ui.draw(c, g, ui_rect, &mut self.glyphs, self.field.total_mines(), self.field.count_marked(), dur);

            let msg_rect = self.get_msg_rect(window);
            self.msg.draw(c, g, msg_rect, &mut self.glyphs);
        });
    }

    fn get_field_rect(&self, window: &PistonWindow) -> [u32; 4] {
        let mut w = window.size().width - self.panel_width;
        w = (w /self.field.get_width()) * self.field.get_width();
        let mut h = window.size().height;
        h = (h /self.field.get_height()) * self.field.get_height();
        [0, 0, w, h]
    }

    fn get_ui_rect(&self, window: &PistonWindow) -> [u32; 4] {
        let mut field_w = window.size().width - self.panel_width;
        field_w = (field_w /self.field.get_width()) * self.field.get_width();
        let w = window.size().width - field_w;
        let h = window.size().height;
        [field_w, 0, w, h]
    }

    fn get_msg_rect(&self, window: &PistonWindow) -> [u32; 4] {
        let w_w = window.size().width;
        let w_h = window.size().height;
        let (m_w, m_h) = EndMessage::size();

        [
            ( (w_w-m_w) / 2 ),
            ( (w_h-m_h) / 2 ),
            m_w,
            m_h
        ]
    }

    pub fn proc_key(&mut self, button: Button, window: &PistonWindow) {
        if self.in_ui {
            match button {
                Button::Keyboard(key) => {
                    match  key {
                        Key::H => {
                            match self.ui.proc_key(ParamType::Height) {
                                Some(h) => {
                                    self.in_ui = false;
                                    self.msg.hide();
                                    self.field.reinit_field(h, ParamType::Height);
                                }
                                _ => {}
                            }
                        },
                        Key::M => {
                            match self.ui.proc_key(ParamType::Mines) {
                                Some(m) => {
                                    self.in_ui = false;
                                    self.msg.hide();
                                    self.field.reinit_field(m, ParamType::Mines);
                                }
                                _ => {}
                            }
                        },
                        Key::W => {
                            match self.ui.proc_key(ParamType::Width) {
                                Some(w) => {
                                    self.in_ui = false;
                                    self.msg.hide();
                                    self.field.reinit_field(w, ParamType::Width);
                                }
                                _ => {}
                            }
                        },
                        Key::Up => self.ui.change_selected(MoveDestination::Up),
                        Key::Down => self.ui.change_selected(MoveDestination::Down),
                        Key::Left => self.ui.change_selected(MoveDestination::Left),
                        Key::Right => self.ui.change_selected(MoveDestination::Right),
                        _ => {}
                    }
                }
                _ => {}
            }
        } else {
            match button {
                Button::Keyboard(key) => {
                    match key {
                        Key::R => self.restart(),
                        Key::Up => self.field.move_selection(MoveDestination::Up),
                        Key::Down => self.field.move_selection(MoveDestination::Down),
                        Key::Left => self.field.move_selection(MoveDestination::Left),
                        Key::Right => self.field.move_selection(MoveDestination::Right),
                        Key::Space => {
                            let ind = self.field.get_selected_ind();
                            self.open_cell(ind);
                        },
                        Key::LCtrl | Key::RCtrl => {
                            let ind = self.field.get_selected_ind();
                            self.toggle_mark(ind);
                        }
                        Key::H => {
                            self.ui.proc_key(ParamType::Height);
                            self.in_ui = true;
                        },
                        Key::M =>{
                            self.ui.proc_key(ParamType::Mines);
                            self.in_ui = true;
                        },
                        Key::W => {
                            self.ui.proc_key(ParamType::Width);
                            self.in_ui = true;
                        },
                        _ => {}
                    }
                },
                Button::Mouse(btn) => {
                    let field_rect = self.get_field_rect(window);
                    let cell_w = field_rect[2] / self.field.get_width();
                    let cell_h = field_rect[3] / self.field.get_height();
                    let mouse_x = self.mouse_x.floor() as u32;
                    let mouse_y = self.mouse_y.floor() as u32;
                    if (mouse_x < field_rect[0]) || (mouse_x > field_rect[0] + field_rect[2]) ||
                       (mouse_y < field_rect[1]) || (mouse_y > field_rect[1] + field_rect[3]) {
                        return;
                    }
                    let x = (mouse_x - field_rect[0]) / cell_w;
                    let y = (mouse_y - field_rect[1]) / cell_h;
                    let w = self.field.get_width();
                    match btn {
                        MouseButton::Left => {
                            self.open_cell(x + y*w);
                        },
                        MouseButton::Right => {

                            self.toggle_mark(x + y*w);
                        },
                        _ => {}
                    }
                }
            }
        }
    }

    fn toggle_mark(&mut self, i: u32) {
        if self.game_ended || self.field.revealed(i) {
            return;
        }
        self.field.toggle_mark(i);
    }

    fn open_cell(&mut self, i: u32) {
        if self.game_ended {
            return;
        }
        if self.game_start == None {
            self.game_start = Some(UTC::now());
        }

        if !self.field.revealed(i) {
            self.check_reveal(i);
        } else {
            self.reveal_neighborhood(i);
        }
    }

    fn reveal_neighborhood(&mut self, i: u32) {
        let cells_count_opt = {
            if let &Content::Number(cells_count) = self.field.get_content(i) {
                Some(cells_count)
            } else {
                None
            }
        };

        if let Some(cells_count) = cells_count_opt {
            if self.field.get_neighborhood_count(i) == cells_count {
                let on_left_edge = i % self.field.get_width() == 0;
                let on_right_edge = (i+1) % self.field.get_width() == 0;

                for rdelta in -1..2i32 {
                    for cdelta in -1..2i32 {
                        if on_left_edge && (cdelta == -1) {
                            continue;
                        }
                        if on_right_edge && (cdelta == 1) {
                            continue;
                        }
                        let tgt = (i as i32) + rdelta*(self.field.get_width() as i32) + cdelta;
                        if (tgt < 0) || (tgt >= self.field.get_size() as i32) {
                            continue;
                        }
                        self.check_reveal(tgt as u32);
                    }
                }
            }
        }
    }

    pub fn check_reveal(&mut self, i : u32) {
        if self.field.marked(i) {
            return;
        }
        match *self.field.reveal(i) {
            Content::Mine(_) => {
                self.field.reveal_all();
                self.game_ended = true;
                self.field.set_killer(i);
                self.game_end = Some(UTC::now());
                self.msg.show( GameEndState::Lose );
                println!("Game over :(");
            },
            Content::None => {
                self.field.chain_reveal(i);
                if self.field.is_victory() {
                    self.msg.show( GameEndState::Win );
                    println!("You win :)");
                    self.game_ended = true;
                    self.game_end = Some(UTC::now());
                }
            }
            Content::Number(_i) => {
                if self.field.is_victory() {
                    self.msg.show( GameEndState::Win );
                    println!("You win :)");
                    self.game_ended = true;
                    self.game_end = Some(UTC::now());
                }
            }
        }
    }

    pub fn mouse_move(&mut self, mouse_rel: [f64; 2]) {
        self.mouse_x = mouse_rel[0];
        self.mouse_y = mouse_rel[1];
    }

    fn restart(&mut self) {
        self.game_ended = false;
        self.msg.hide();
        self.game_start = None;
        self.game_end = None;
        self.field.restart();
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use types::{LispToken, LispFunc};

macro_rules! lisp_func(
	(|$ee:ident, $args:ident| -> $fun:expr) => (LispFunc::new(box |$ee, args| -> LispToken {
		match args {
			&LispToken::List(ref $args) => $fun,
			_ => panic!("Invalid Argument Error")
		}
	}))
);

macro_rules! lisp_fold_func(
	(|$ee:ident, $args:ident| -> { $temp:ident = $start:expr + |$acc:ident, $elem:ident| -> $fun:expr; $wrap:expr } ) =>
		( lisp_func!(|$ee, $args| -> {
			let $temp = args.iter().fold( $start, |$acc, $elem| { $fun } );
			$wrap
		}) );
	(|$ee:ident, $args:ident| -> { $temp:ident = |$acc:ident, $elem:ident| -> $fun:expr; $wrap:expr } ) =>
		( lisp_func!(|$ee, $args| -> {
			let $temp = args.iter().skip(1).fold( $args[0], |$acc, $elem| { $fun } );
			$wrap
	} ) );
);

macro_rules! lisp_map_func(
	(|$ee:ident, $args:ident| -> |$arg:ident| -> $map:expr) =>
		( lisp_func!( |$ee, $args| -> LispToken::List(args.iter().map(|$arg| { $map }.collect()) ) ) )
);

macro_rules! lisp_filter_func(
	(|$ee:ident, $args:ident| -> |$arg:ident| -> $filter:expr) =>
		( lisp_func!( |$ee, $args| -> LispToken::List(args.iter().map(|$arg| { $filter }.collect()) ) ) )
);

macro_rules! check_arg!(
	($elem:ident, $arg:pat, $then:expr) => (match $elem {
		$arg => $then,
		_ => panic!("Invalid Argument Error")
	})
)

macro_rules! math_fold_funct(
	(|$a:ident, $n:ident| -> $fun:expr) => { lisp_func!( |ee, arg_list| -> match arg_list[0] {
				LispToken::Integer(i) => LispToken::Integer(arg_list.iter().skip(1).fold(i, |$a, elem| {
					match elem {
						&LispToken::Integer($n) => $fun,
						&LispToken::FloatingPoint(f) => {
							let $n = f as i32;
							$fun
						},
						_ => panic!("Invalid Argument Error")
					}
				})),
				LispToken::FloatingPoint(f) => LispToken::FloatingPoint(arg_list.iter().skip(1).fold(f, |$a, elem| {
					match elem {
						&LispToken::Integer(i) => {
							let $n = i as f64;
							$fun
						},
						&LispToken::FloatingPoint($n) => $fun,
						_ => panic!("Invalid Argument Error")
					}
				})),
				_ => panic!("Invalid Argument Error")
			})
	}
);

pub fn init_functs(functs: &mut HashMap<&str, LispFunc>) {
	functs.insert("+", math_fold_funct!(|a, n| -> a + n));
	functs.insert("*", math_fold_funct!(|a, n| -> a * n));
	functs.insert("-", math_fold_funct!(|a, n| -> a - n));
	functs.insert("/", math_fold_funct!(|a, n| -> a / n));
	functs.insert("concat", lisp_fold_func!(|ee, args| -> ));
}<commit_msg>Macro rules fix<commit_after>use std::collections::HashMap;
use types::{LispToken, LispFunc};

macro_rules! lisp_func(
	($ee:ident, $args:ident => $fun:expr) => (LispFunc::new(box |$ee, args| -> LispToken {
		match args {
			&LispToken::List(ref $args) => $fun,
			_ => panic!("Invalid Argument Error")
		}
	}))
);

macro_rules! lisp_fold_func(
	( $ee:ident, $args:ident => $start:expr :: $acc:ident, $elem:ident => $fun:expr : $temp:ident => $wrap:expr ) =>
		( lisp_func!($ee, $args => {
			let $temp = $args.iter().fold( $start, |$acc, $elem| { $fun } );
			$wrap
		}) );
	( $ee:ident, $args:ident => $acc:ident, $elem:ident => $fun:expr : $temp:ident => $wrap:expr ) =>
		( lisp_func!($ee, $args => {
			let $temp = args.iter().skip(1).fold( $args[0], |$acc, $elem| { $fun } );
			$wrap
	} ) );
);

macro_rules! lisp_map_func(
	($ee:ident, $args:ident => $arg:ident => $map:expr) =>
		( lisp_func!( $ee, $args => LispToken::List(args.iter().map(|$arg| { $map }.collect()) ) ) )
);

macro_rules! lisp_filter_func(
	($ee:ident, $args:ident => $arg:ident => $filter:expr) =>
		( lisp_func!( $ee, $args => LispToken::List(args.iter().map(|$arg| { $filter }.collect()) ) ) )
);

macro_rules! check_arg(
	($elem:ident, $arg:pat => $then:expr) => (match $elem {
		$arg => $then,
		_ => panic!("Invalid Argument Error")
	})
);

macro_rules! math_fold_funct(
	($a:ident, $n:ident => $fun:expr) => { lisp_func!( ee, arg_list => match arg_list[0] {
				LispToken::Integer(i) => LispToken::Integer(arg_list.iter().skip(1).fold(i, |$a, elem| {
					match elem {
						&LispToken::Integer($n) => $fun,
						&LispToken::FloatingPoint(f) => {
							let $n = f as i32;
							$fun
						},
						_ => panic!("Invalid Argument Error")
					}
				})),
				LispToken::FloatingPoint(f) => LispToken::FloatingPoint(arg_list.iter().skip(1).fold(f, |$a, elem| {
					match elem {
						&LispToken::Integer(i) => {
							let $n = i as f64;
							$fun
						},
						&LispToken::FloatingPoint($n) => $fun,
						_ => panic!("Invalid Argument Error")
					}
				})),
				_ => panic!("Invalid Argument Error")
			})
	}
);

pub fn init_functs(functs: &mut HashMap<&str, LispFunc>) {
	functs.insert("+", math_fold_funct!(a, n => a + n));
	functs.insert("*", math_fold_funct!(a, n => a * n));
	functs.insert("-", math_fold_funct!(a, n => a - n));
	functs.insert("/", math_fold_funct!(a, n => a / n));
	functs.insert("concat",
		lisp_fold_func!(ee, args =>
			"".to_string() :: acc, elem =>
				{ acc + elem.as_str().as_slice() }
					: temp => LispToken::String(temp) )
	);
}<|endoftext|>