I don't know the used code in UnityEngine.JsonUtility
the spec for your morgue file is the class effectively, but if you change the morgue class, the spec changes, and the previous morgue files are worthless.
I don't know if this is the case, but I would gather that it is.
I have made many additions to the morgue class and never ran into old morgues breaking.
They parse the new fields as empty.
Maybe I'm getting lucky, or maybe it would crash if I REMOVE a field rather than adding more.
that's the point: you need to elevate to the midwit handling of all cases. this is the type of thinking that lets you build frankenstein'd out behemoths of software.
I was thinking that if someone tampers with the json files and makes his game crash it's not my fault if I leave him to die.
Sorting data based on score? Here you go:
scores.Sort((x, y) => -1 * x.score.CompareTo(y.score));
genius
genius?
...
scores.Sort((x, y) => y.score.CompareTo(x.score));
john carmac over here
fn find_valid_hands(tiles: &[u8; 34]) -> Vec<[u8; 34]> {
let mut valid_hands = Vec::new();
// Determine each triplet, sequence, and pair, then look at all potential
// combinations to find the set of valid hands.
let triplets: Vec<(usize, usize, usize)> = Yaku::find_triplets(&tiles)
.iter()
.map(|x| (*x, *x, *x))
.collect();
let sequences: Vec<(usize, usize, usize)> =
Yaku::find_sequences(&tiles).iter().map(|x| *x).collect();
let melds = [triplets, sequences].concat();
let jantou = Yaku::find_pairs(&tiles);
// A hand requires 4 melds and 1 pair; if this isn't met, exit.
// TODO: Handle chiitoitsu, etc.
if melds.len() < 4 || jantou.len() < 1 {
return valid_hands;
}
fn assemble(
melds: &[(usize, usize, usize)],
jantou: &[usize],
pool: &[u8; 34],
hand: &[u8; 34],
depth: usize,
found: &mut Vec<[u8; 34]>,
) {
let range = match depth {
4 => 0..jantou.len(),
// If we have N melds, the K'th meld cannot be the N-K meld because there wouldn't
// be enough melds left to compose a valid hand.
// _ => depth..melds.len() - (3 - depth),
// _ => depth..melds.len(),
// TODO: It should be the case that we can constrain this range
// but in this implementation, it's just not working.
_ => 0..melds.len(),
};
let potential_meld = |meld: (usize, usize, usize)| -> Option<([u8; 34], [u8; 34])> {
let mut new_pool = pool.clone();
let mut new_hand = hand.clone();
// If this underflows, we propagate the `None` upwards indicating this isn't a usable meld.
new_pool[meld.0] = new_pool[meld.0].checked_sub(1)?;
new_pool[meld.1] = new_pool[meld.1].checked_sub(1)?;
new_pool[meld.2] = new_pool[meld.2].checked_sub(1)?;
new_hand[meld.0] += 1;
new_hand[meld.1] += 1;
new_hand[meld.2] += 1;
Some((new_pool, new_hand))
};
match depth {
4 => {
for i in range {
if pool[jantou[i]] > 1 {
let mut found_hand = hand.clone();
found_hand[jantou[i]] += 2;
found.push(found_hand);
}
}
}
_ => {
for i in range {
if let Some((new_pool, new_hand)) = potential_meld(melds[i]) {
assemble(melds, jantou, &new_pool, &new_hand, depth + 1, found);
} else {
continue;
}
}
}
};
}
assemble(&melds, &jantou, tiles, &[0u8; 34], 0, &mut valid_hands);
valid_hands
}
Main issue with this code (and nmagane's) is that it is not pythonic.
My server code is literally in python
nah I just need to remove the sequence/jantou creation and place it in a different function. I could pass a [usize; 3]
rather than a tuple in potential_meld
and it might give the compiler an option to vectorize?
it'd be nice to make assemble
a closure but recursive closures in rust require a hack.
You could turn Vec<[u8; 34]>
into a trie of some sort.
What's the tool or plugin