Sudoku up through chapter 7
This commit is contained in:
parent
7d2ac20ce1
commit
7f2f579241
@ -1,21 +1,42 @@
|
|||||||
//! Game board logic.
|
//! Game board logic.
|
||||||
|
|
||||||
|
use std::fs::read_to_string;
|
||||||
|
|
||||||
const SIZE: usize = 9;
|
const SIZE: usize = 9;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||||
|
pub struct Cell {
|
||||||
|
pub value: u8,
|
||||||
|
pub loaded: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Gameboard {
|
pub struct Gameboard {
|
||||||
pub cells: [[u8; SIZE]; SIZE],
|
pub cells: [[Cell; SIZE]; SIZE],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gameboard {
|
impl Gameboard {
|
||||||
pub fn new() -> Gameboard {
|
pub fn new() -> Gameboard {
|
||||||
Gameboard {
|
Gameboard {
|
||||||
cells: [[0; SIZE]; SIZE],
|
cells: [[Cell::default(); SIZE]; SIZE],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_cells(cells: [[u8; SIZE]; SIZE]) -> Gameboard {
|
||||||
|
let mut ret = Gameboard::new();
|
||||||
|
for (i, row) in cells.iter().enumerate() {
|
||||||
|
for (j, &col) in row.iter().enumerate() {
|
||||||
|
ret.cells[i][j] = Cell {
|
||||||
|
value: col,
|
||||||
|
loaded: col != 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
pub fn char(&self, ind: [usize; 2]) -> Option<char> {
|
pub fn char(&self, ind: [usize; 2]) -> Option<char> {
|
||||||
Some(match self.cells[ind[1]][ind[0]] {
|
Some(match self.cells[ind[1]][ind[0]].value {
|
||||||
1 => '1',
|
1 => '1',
|
||||||
2 => '2',
|
2 => '2',
|
||||||
3 => '3',
|
3 => '3',
|
||||||
@ -30,14 +51,14 @@ impl Gameboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, ind: [usize; 2], val: u8) {
|
pub fn set(&mut self, ind: [usize; 2], val: u8) {
|
||||||
self.cells[ind[1]][ind[0]] = val;
|
if !self.cells[ind[1]][ind[0]].loaded {
|
||||||
|
self.cells[ind[1]][ind[0]].value = val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_sdm(filename: &str) -> Self {
|
pub fn load_sdm(filename: &str) -> Self {
|
||||||
use std::fs::read_to_string;
|
|
||||||
|
|
||||||
let data = read_to_string(filename).expect("failed to read SDM file");
|
let data = read_to_string(filename).expect("failed to read SDM file");
|
||||||
let mut cells = [[0; SIZE]; SIZE];
|
let mut cells = [[Cell::default(); SIZE]; SIZE];
|
||||||
let mut row = 0;
|
let mut row = 0;
|
||||||
let mut col = 0;
|
let mut col = 0;
|
||||||
for c in data.chars() {
|
for c in data.chars() {
|
||||||
@ -45,8 +66,12 @@ impl Gameboard {
|
|||||||
col = 0;
|
col = 0;
|
||||||
row += 1;
|
row += 1;
|
||||||
}
|
}
|
||||||
if let Some(d) = c.to_digit(10) {
|
if let Some(v) = c.to_digit(10) {
|
||||||
cells[row][col] = d as u8;
|
let value = v as u8;
|
||||||
|
cells[row][col] = Cell {
|
||||||
|
value,
|
||||||
|
loaded: value != 0,
|
||||||
|
};
|
||||||
col += 1;
|
col += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,19 +87,17 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn load_sdm() {
|
fn load_sdm() {
|
||||||
let got = Gameboard::load_sdm("static/puzzle.sdm");
|
let got = Gameboard::load_sdm("static/puzzle.sdm");
|
||||||
let want = Gameboard {
|
let want = Gameboard::from_cells([
|
||||||
cells: [
|
[0, 1, 6, 4, 0, 0, 0, 0, 0],
|
||||||
[0, 1, 6, 4, 0, 0, 0, 0, 0],
|
[2, 0, 0, 0, 0, 9, 0, 0, 0],
|
||||||
[2, 0, 0, 0, 0, 9, 0, 0, 0],
|
[4, 0, 0, 0, 0, 0, 0, 6, 2],
|
||||||
[4, 0, 0, 0, 0, 0, 0, 6, 2],
|
[0, 7, 0, 2, 3, 0, 1, 0, 0],
|
||||||
[0, 7, 0, 2, 3, 0, 1, 0, 0],
|
[1, 0, 0, 0, 0, 0, 0, 0, 3],
|
||||||
[1, 0, 0, 0, 0, 0, 0, 0, 3],
|
[0, 0, 3, 0, 8, 7, 0, 4, 0],
|
||||||
[0, 0, 3, 0, 8, 7, 0, 4, 0],
|
[9, 6, 0, 0, 0, 0, 0, 0, 5],
|
||||||
[9, 6, 0, 0, 0, 0, 0, 0, 5],
|
[0, 0, 0, 8, 0, 0, 0, 0, 7],
|
||||||
[0, 0, 0, 8, 0, 0, 0, 0, 7],
|
[0, 0, 0, 0, 0, 6, 8, 2, 0],
|
||||||
[0, 0, 0, 0, 0, 6, 8, 2, 0],
|
]);
|
||||||
],
|
|
||||||
};
|
|
||||||
assert_eq!(got, want);
|
assert_eq!(got, want);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ pub struct GameboardViewSettings {
|
|||||||
pub cell_edge_radius: f64,
|
pub cell_edge_radius: f64,
|
||||||
pub selected_cell_background_color: Color,
|
pub selected_cell_background_color: Color,
|
||||||
pub text_color: Color,
|
pub text_color: Color,
|
||||||
|
pub loaded_cell_background_color: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameboardViewSettings {
|
impl GameboardViewSettings {
|
||||||
@ -36,6 +37,7 @@ impl GameboardViewSettings {
|
|||||||
cell_edge_radius: 1.0,
|
cell_edge_radius: 1.0,
|
||||||
selected_cell_background_color: [0.9, 0.9, 1.0, 1.0],
|
selected_cell_background_color: [0.9, 0.9, 1.0, 1.0],
|
||||||
text_color: [0.0, 0.0, 0.1, 1.0],
|
text_color: [0.0, 0.0, 0.1, 1.0],
|
||||||
|
loaded_cell_background_color: [1.0, 1.0, 1.0, 1.0],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,21 +72,27 @@ impl GameboardView {
|
|||||||
|
|
||||||
Rectangle::new(settings.background_color).draw(board_rect, &c.draw_state, c.transform, g);
|
Rectangle::new(settings.background_color).draw(board_rect, &c.draw_state, c.transform, g);
|
||||||
|
|
||||||
|
for i in 0..9 {
|
||||||
|
for j in 0..9 {
|
||||||
|
if controller.gameboard.cells[i][j].loaded {
|
||||||
|
color_cell(
|
||||||
|
settings,
|
||||||
|
[j, i],
|
||||||
|
settings.loaded_cell_background_color,
|
||||||
|
c,
|
||||||
|
g,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(ind) = controller.selected_cell {
|
if let Some(ind) = controller.selected_cell {
|
||||||
let cell_size = settings.size / 9.0;
|
let color = if !controller.gameboard.cells[ind[1]][ind[0]].loaded {
|
||||||
let pos = [ind[0] as f64 * cell_size, ind[1] as f64 * cell_size];
|
settings.selected_cell_background_color
|
||||||
let cell_rect = [
|
} else {
|
||||||
settings.position[0] + pos[0],
|
settings.loaded_cell_background_color
|
||||||
settings.position[1] + pos[1],
|
};
|
||||||
cell_size,
|
color_cell(settings, ind, color, c, g);
|
||||||
cell_size,
|
|
||||||
];
|
|
||||||
Rectangle::new(settings.selected_cell_background_color).draw(
|
|
||||||
cell_rect,
|
|
||||||
&c.draw_state,
|
|
||||||
c.transform,
|
|
||||||
g,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let text_image = Image::new_color(settings.text_color);
|
let text_image = Image::new_color(settings.text_color);
|
||||||
@ -147,3 +155,23 @@ impl GameboardView {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn color_cell<G: Graphics>(
|
||||||
|
settings: &GameboardViewSettings,
|
||||||
|
ind: [usize; 2],
|
||||||
|
color: [f32; 4],
|
||||||
|
c: &Context,
|
||||||
|
g: &mut G,
|
||||||
|
) {
|
||||||
|
use graphics::Rectangle;
|
||||||
|
|
||||||
|
let cell_size = settings.size / 9.0;
|
||||||
|
let pos = [ind[0] as f64 * cell_size, ind[1] as f64 * cell_size];
|
||||||
|
let cell_rect = [
|
||||||
|
settings.position[0] + pos[0],
|
||||||
|
settings.position[1] + pos[1],
|
||||||
|
cell_size,
|
||||||
|
cell_size,
|
||||||
|
];
|
||||||
|
Rectangle::new(color).draw(cell_rect, &c.draw_state, c.transform, g);
|
||||||
|
}
|
||||||
|
@ -27,7 +27,7 @@ fn main() {
|
|||||||
let mut events = Events::new(EventSettings::new().lazy(true));
|
let mut events = Events::new(EventSettings::new().lazy(true));
|
||||||
let mut gl = GlGraphics::new(opengl);
|
let mut gl = GlGraphics::new(opengl);
|
||||||
|
|
||||||
let gameboard = Gameboard::new();
|
let gameboard = Gameboard::load_sdm("static/puzzle.sdm");
|
||||||
let mut gameboard_controller = GameboardController::new(gameboard);
|
let mut gameboard_controller = GameboardController::new(gameboard);
|
||||||
let gameboard_view_settings = GameboardViewSettings::new();
|
let gameboard_view_settings = GameboardViewSettings::new();
|
||||||
let gameboard_view = GameboardView::new(gameboard_view_settings);
|
let gameboard_view = GameboardView::new(gameboard_view_settings);
|
||||||
|
Loading…
Reference in New Issue
Block a user