use rand;
use rand::Rng;
pub mod mino;
use mino::Mino;
pub mod board;
use board::Board;
use crate::stat::Stat;
pub struct Model {
pub minos: Vec<Mino>,
pub f: u32,
pub b: Board
}
impl Model {
pub fn new(w: u16, h: u16) -> Self {
Model{minos: Mino::gen_minos(), f: 0, b: Board::new(w, h)}
}
pub fn put_mino(&mut self, s: &Stat, action: u16) -> u16 {
let (t, c) = if action == 2 { (0, 0) } else { (2, 1 + s.typ) };
if action != 2 && self.b.get_dot(s.x, s.y) & 0xf0 != 0 { return 0; }
if action != 0 { self.b.draw_dot(s.x, s.y, t, c); }
let m = &self.minos[s.typ as usize];
for q in m.pos.iter() {
let (mut dx, mut dy) = (q.x, q.y);
let r = s.rotate % m.rotate;
for _j in 0..r {
let (nx, ny) = (dx, dy);
(dx, dy) = (ny, -nx);
}
let (ux, uy) = ((s.x as i16 + dx) as u16, (s.y as i16 + dy) as u16);
if action != 2 && self.b.get_dot(ux, uy) & 0xf0 != 0 { return 0; }
if action != 0 { self.b.draw_dot(ux, uy, t, c); }
}
if action == 0 { self.put_mino(s, 1); }
1
}
pub fn delete_mino(&mut self, s: &Stat) -> u16 {
self.put_mino(s, 2)
}
pub fn i_rand(m: u8) -> u8 {
(rand::thread_rng().gen_range(0..m as u32 * 65536) % m as u32) as u8
}
pub fn new_mino(&mut self) -> Stat {
Stat{
x: self.b.w / 2,
y: self.b.h + 1,
rotate: Self::i_rand(4),
typ: Self::i_rand(self.minos.len() as u8 - 1) + 1} }
pub fn init_board(&mut self, s: &mut Stat) {
self.b.clear_board();
self.b.draw_box();
*s = self.new_mino();
self.put_mino(s, 0);
}
pub fn over(&mut self) {
for r in self.b.fld.iter_mut() {
for c in r {
if *c & 0x20 != 0 { *c |= 0x0f; }
}
}
}
pub fn delete_line(&mut self) -> u16 {
let mut n = 0;
for r in 1..self.b.h - 2 {
let mut flg = true;
while flg {
for c in 1..self.b.w + 1 {
if self.b.get_dot(c, r) == 0 { flg = false; }
}
if !flg { break; }
n += 1;
for j in r..self.b.h - 2 {
for i in 1..self.b.w + 1 {
self.b.draw_dot_copy(i, j, i, j + 1);
}
}
}
}
n
}
pub fn down_mino(&mut self, s: &mut Stat) -> u16 {
self.delete_mino(s);
s.y -= 1;
if self.put_mino(s, 0) == 0 {
s.y += 1;
self.put_mino(s, 0);
self.delete_line();
*s = self.new_mino();
if self.put_mino(s, 0) == 0 { self.over(); return 1; } self.f = 0;
return 2; }
0 }
pub fn proc_key(&mut self, s: &mut Stat, k: u8) -> u16 {
let mut ret = 0;
let mut n = Stat::new(s.x, s.y, s.rotate, s.typ);
match k {
0 => { ret = 1; }, 1 => { n.x -= 1; },
2 => { n.x += 1; },
3 => { n.rotate += 1; },
4 => { ret = 1; },
_ => { ret = 0; }
}
if n.x != s.x || n.y != s.y || n.rotate != s.rotate {
self.delete_mino(s);
if self.put_mino(&n, 0) != 0 {
*s = n;
} else {
self.put_mino(s, 0);
}
}
if ret == 1 { self.f = 1; }
ret
}
}