Closed kvark closed 9 years ago
pub type Coordinate = (int,int,int); static MaxSize : uint = 20; struct Point(float,float,float); impl core::ops::Add<Point,Point> for Point { fn add( &self, rhs: &Point )-> Point { let Point(x1,y1,z1) = *self; let Point(x2,y2,z2) = *rhs; Point( x1+x2, y1+y2, z1+z2 ) } } impl core::ops::Mul<float,Point> for Point { fn mul( &self, rhs: &float )-> Point { let Point(x,y,z) = *self; Point( x**rhs, y**rhs, z**rhs ) } } pub enum Cell<Unit> { CellEmpty, CellObstacle, CellUnit(Unit), } impl<Unit:Copy> Copy for Cell<Unit>; //TODO: use new iterators trait PureGrid { fn get_neighbours( c : Coordinate )-> ~[Coordinate]; fn get_center( &self, c : Coordinate )-> Point; fn get_coordinate( &self, p : Point )-> Coordinate; fn is_out_bounds( &self, c : Coordinate )-> bool; } trait Grid<Unit> : PureGrid { fn mut_cell( &mut self, c : Coordinate, fun : &fn(&mut Cell<Unit>) )-> bool; } struct Grid2D<Unit> { corner : Point, side : float, dim : (uint,uint), cells : [[Cell<Unit>, ..MaxSize], ..MaxSize], } // Quad // pub struct GridQuad<Unit>( Grid2D<Unit> ); impl<Unit> PureGrid for GridQuad<Unit> { fn get_neighbours( c : Coordinate )-> ~[Coordinate] { let (i,j,k) = c; ~[ (i+1,j,k), (i,j+1,k), (i-1,j,k), (i,j-1,k) ] } fn get_center( &self, c : Coordinate )-> Point { let (i,j,_) = c; self.corner + Point(i as float,j as float,0f) * self.side } fn get_coordinate( &self, p : Point )-> Coordinate { let Point(x,y,_) = (p + self.corner*-1f) * (1f/self.side); (x as int, y as int, 0) } fn is_out_bounds( &self, c : Coordinate )-> bool { let (i,j,_) = c, (dx,dy) = self.dim; i<0 || j<0 || i>=dx as int || j>=dy as int } } impl<Unit> Grid<Unit> for GridQuad<Unit> { fn mut_cell( &mut self, c : Coordinate, fun : &fn(&mut Cell<Unit>) )-> bool { if self.is_out_bounds( c ) { false }else { let (i,j,_) = c; fun( &mut self.cells[i][j] ); true } } } // Triangle // pub struct GridTriangle<Unit>( Grid2D<Unit> ); impl<Unit> PureGrid for GridTriangle<Unit> { fn get_neighbours( c : Coordinate )-> ~[Coordinate] { let (i,j,k) = c; match j&3 { 0 => ~[ (i,j+1,k), (i-1,j+1,k), (i,j-1,k) ], 1 => ~[ (i+1,j-1,k), (i,j+1,k), (i,j-1,k) ], 2 => ~[ (i+1,j+1,k), (i,j+1,k), (i,j-1,k) ], 3 => ~[ (i,j-1,k), (i,j+1,k), (i-1,j-1,k) ], _ => fail!(~"") } } fn get_center( &self, c : Coordinate )-> Point { let (i,j,_) = c; let ho3 = self.side * float::sqrt(3f) / 6f; let x = (i as float)*self.side + if (j+1)&2==0 {0f} else {0.5f*self.side}; let y = (((j+1)/2) as float)*ho3*3f + if j&1==0 {ho3} else {-ho3}; self.corner + Point(x,y,0f) } fn get_coordinate( &self, p : Point )-> Coordinate { let Point(x,y,_) = p; let h = self.side * float::sqrt(3f) / 2f; let jt = (y/h) as int; let y0 = (jt as float) * h; let xt = x - (y-y0) * self.side / h; let i = (xt/self.side) as int; let x0 = (i as float) * self.side; let j = 2*jt + (if x-x0+y-y0 > self.side {1} else {0}); (i,j,0) } fn is_out_bounds( &self, c : Coordinate )-> bool { let (i,j,_) = c, (dx,dy) = self.dim; i<0 || j<0 || i>=dx as int || j>=dy as int } } impl<Unit> Grid<Unit> for GridTriangle<Unit> { fn mut_cell( &mut self, c : Coordinate, fun : &fn(&mut Cell<Unit>) )-> bool { if self.is_out_bounds( c ) { false }else { let (i,j,_) = c; fun( &mut self.cells[i][j] ); true } } } // ----- // pub fn create_grid<Unit:Copy+Owned>( topology : uint, dim : (uint,uint), side : float )-> ~Grid<Unit> { let base : Grid2D<Unit> = Grid2D{ corner : Point(0f,0f,0f), side : side, dim : dim, cells : [[CellEmpty, ..MaxSize], ..MaxSize], }; match topology { 3 => ~GridTriangle( base ) as ~Grid<Unit>, 4 => ~GridQuad ( base ) as ~Grid<Unit>, _ => fail!(fmt!( "Unsupported topology %u", topology )) } } fn main() { //empty }
Alternatively, use https://github.com/dpc/hex2d-rs
Or https://github.com/kvark/grid-rs Related to #17
Grid is abstracted away now, and the relevant issues will be created for grid-rs.