Remove piston tutorials
This commit is contained in:
parent
cf91122a57
commit
7fb96a8db7
1876
piston-tutorials/getting-started/Cargo.lock
generated
1876
piston-tutorials/getting-started/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,17 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "spinning-square"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = [
|
|
||||||
"Dan Buch <dan@meatballhat.com>",
|
|
||||||
"TyOverby <ty@pre-alpha.com>",
|
|
||||||
"Nikita Pekin <contact@nikitapek.in>"
|
|
||||||
]
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "spinning-square"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
piston = "0.53.0"
|
|
||||||
piston2d-graphics = "0.43.0"
|
|
||||||
pistoncore-glutin_window = "0.70.1"
|
|
||||||
piston2d-opengl_graphics = "0.82.0"
|
|
@ -1,70 +0,0 @@
|
|||||||
extern crate glutin_window;
|
|
||||||
extern crate graphics;
|
|
||||||
extern crate opengl_graphics;
|
|
||||||
extern crate piston;
|
|
||||||
|
|
||||||
use glutin_window::GlutinWindow as Window;
|
|
||||||
use opengl_graphics::{GlGraphics, OpenGL};
|
|
||||||
use piston::event_loop::{EventSettings, Events};
|
|
||||||
use piston::input::{RenderArgs, RenderEvent, UpdateArgs, UpdateEvent};
|
|
||||||
use piston::window::WindowSettings;
|
|
||||||
|
|
||||||
pub struct App {
|
|
||||||
gl: GlGraphics,
|
|
||||||
rotation: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl App {
|
|
||||||
fn render(&mut self, args: &RenderArgs) {
|
|
||||||
use graphics::*;
|
|
||||||
|
|
||||||
const GREEN: [f32; 4] = [0.0, 1.0, 0.0, 1.0];
|
|
||||||
const RED: [f32; 4] = [1.0, 0.0, 0.0, 1.0];
|
|
||||||
|
|
||||||
let square = rectangle::square(0.0, 0.0, 50.0);
|
|
||||||
let rotation = self.rotation;
|
|
||||||
let (x, y) = (args.window_size[0] / 2.0, args.window_size[1] / 2.0);
|
|
||||||
|
|
||||||
self.gl.draw(args.viewport(), |c, gl| {
|
|
||||||
clear(GREEN, gl);
|
|
||||||
|
|
||||||
let transform = c
|
|
||||||
.transform
|
|
||||||
.trans(x, y)
|
|
||||||
.rot_rad(rotation)
|
|
||||||
.trans(-25.0, -25.0);
|
|
||||||
|
|
||||||
rectangle(RED, square, transform, gl);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update(&mut self, args: &UpdateArgs) {
|
|
||||||
self.rotation += 2.0 * args.dt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let opengl = OpenGL::V3_2;
|
|
||||||
|
|
||||||
let mut window: Window = WindowSettings::new("spinning-square", [200, 200])
|
|
||||||
.graphics_api(opengl)
|
|
||||||
.exit_on_esc(true)
|
|
||||||
.build()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut app = App {
|
|
||||||
gl: GlGraphics::new(opengl),
|
|
||||||
rotation: 0.0,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut events = Events::new(EventSettings::new());
|
|
||||||
while let Some(e) = events.next(&mut window) {
|
|
||||||
if let Some(args) = e.render_args() {
|
|
||||||
app.render(&args);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(args) = e.update_args() {
|
|
||||||
app.update(&args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
1876
piston-tutorials/sudoku/Cargo.lock
generated
1876
piston-tutorials/sudoku/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,12 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "sudoku"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
piston = "0.53.2"
|
|
||||||
piston2d-graphics = "0.43.0"
|
|
||||||
piston2d-opengl_graphics = "0.82.0"
|
|
||||||
pistoncore-glutin_window = "0.70.1"
|
|
Binary file not shown.
@ -1,99 +0,0 @@
|
|||||||
Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
|
|
||||||
with Reserved Font Name Fira Sans.
|
|
||||||
|
|
||||||
Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
|
|
||||||
with Reserved Font Name Fira Mono.
|
|
||||||
|
|
||||||
Copyright (c) 2014, Telefonica S.A.
|
|
||||||
|
|
||||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
||||||
This license is copied below, and is also available with a FAQ at:
|
|
||||||
http://scripts.sil.org/OFL
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------------------------------
|
|
||||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
||||||
-----------------------------------------------------------
|
|
||||||
|
|
||||||
PREAMBLE
|
|
||||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
||||||
development of collaborative font projects, to support the font creation
|
|
||||||
efforts of academic and linguistic communities, and to provide a free and
|
|
||||||
open framework in which fonts may be shared and improved in partnership
|
|
||||||
with others.
|
|
||||||
|
|
||||||
The OFL allows the licensed fonts to be used, studied, modified and
|
|
||||||
redistributed freely as long as they are not sold by themselves. The
|
|
||||||
fonts, including any derivative works, can be bundled, embedded,
|
|
||||||
redistributed and/or sold with any software provided that any reserved
|
|
||||||
names are not used by derivative works. The fonts and derivatives,
|
|
||||||
however, cannot be released under any other type of license. The
|
|
||||||
requirement for fonts to remain under this license does not apply
|
|
||||||
to any document created using the fonts or their derivatives.
|
|
||||||
|
|
||||||
DEFINITIONS
|
|
||||||
"Font Software" refers to the set of files released by the Copyright
|
|
||||||
Holder(s) under this license and clearly marked as such. This may
|
|
||||||
include source files, build scripts and documentation.
|
|
||||||
|
|
||||||
"Reserved Font Name" refers to any names specified as such after the
|
|
||||||
copyright statement(s).
|
|
||||||
|
|
||||||
"Original Version" refers to the collection of Font Software components as
|
|
||||||
distributed by the Copyright Holder(s).
|
|
||||||
|
|
||||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
||||||
or substituting -- in part or in whole -- any of the components of the
|
|
||||||
Original Version, by changing formats or by porting the Font Software to a
|
|
||||||
new environment.
|
|
||||||
|
|
||||||
"Author" refers to any designer, engineer, programmer, technical
|
|
||||||
writer or other person who contributed to the Font Software.
|
|
||||||
|
|
||||||
PERMISSION & CONDITIONS
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
||||||
redistribute, and sell modified and unmodified copies of the Font
|
|
||||||
Software, subject to the following conditions:
|
|
||||||
|
|
||||||
1) Neither the Font Software nor any of its individual components,
|
|
||||||
in Original or Modified Versions, may be sold by itself.
|
|
||||||
|
|
||||||
2) Original or Modified Versions of the Font Software may be bundled,
|
|
||||||
redistributed and/or sold with any software, provided that each copy
|
|
||||||
contains the above copyright notice and this license. These can be
|
|
||||||
included either as stand-alone text files, human-readable headers or
|
|
||||||
in the appropriate machine-readable metadata fields within text or
|
|
||||||
binary files as long as those fields can be easily viewed by the user.
|
|
||||||
|
|
||||||
3) No Modified Version of the Font Software may use the Reserved Font
|
|
||||||
Name(s) unless explicit written permission is granted by the corresponding
|
|
||||||
Copyright Holder. This restriction only applies to the primary font name as
|
|
||||||
presented to the users.
|
|
||||||
|
|
||||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
||||||
Software shall not be used to promote, endorse or advertise any
|
|
||||||
Modified Version, except to acknowledge the contribution(s) of the
|
|
||||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
||||||
permission.
|
|
||||||
|
|
||||||
5) The Font Software, modified or unmodified, in part or in whole,
|
|
||||||
must be distributed entirely under this license, and must not be
|
|
||||||
distributed under any other license. The requirement for fonts to
|
|
||||||
remain under this license does not apply to any document created
|
|
||||||
using the Font Software.
|
|
||||||
|
|
||||||
TERMINATION
|
|
||||||
This license becomes null and void if any of the above conditions are
|
|
||||||
not met.
|
|
||||||
|
|
||||||
DISCLAIMER
|
|
||||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
||||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
||||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
||||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
||||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@ -1,155 +0,0 @@
|
|||||||
//! Game board logic.
|
|
||||||
|
|
||||||
use std::fs::read_to_string;
|
|
||||||
|
|
||||||
const SIZE: usize = 9;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
|
||||||
pub struct Cell {
|
|
||||||
pub value: u8,
|
|
||||||
pub loaded: bool,
|
|
||||||
pub invalid: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub struct Gameboard {
|
|
||||||
pub cells: [[Cell; SIZE]; SIZE],
|
|
||||||
pub completed: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Gameboard {
|
|
||||||
pub fn new() -> Gameboard {
|
|
||||||
Gameboard {
|
|
||||||
cells: [[Cell::default(); SIZE]; SIZE],
|
|
||||||
completed: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
|
||||||
invalid: false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn char(&self, ind: [usize; 2]) -> Option<char> {
|
|
||||||
Some(match self.cells[ind[1]][ind[0]].value {
|
|
||||||
1 => '1',
|
|
||||||
2 => '2',
|
|
||||||
3 => '3',
|
|
||||||
4 => '4',
|
|
||||||
5 => '5',
|
|
||||||
6 => '6',
|
|
||||||
7 => '7',
|
|
||||||
8 => '8',
|
|
||||||
9 => '9',
|
|
||||||
_ => return None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set(&mut self, ind: [usize; 2], val: u8) {
|
|
||||||
if !self.cells[ind[1]][ind[0]].loaded {
|
|
||||||
self.validate(ind, val);
|
|
||||||
self.cells[ind[1]][ind[0]].value = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.completed = self
|
|
||||||
.cells
|
|
||||||
.iter()
|
|
||||||
.flatten()
|
|
||||||
.all(|cell| !cell.invalid && cell.value != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_sdm(filename: &str) -> Self {
|
|
||||||
let data = read_to_string(filename).expect("failed to read SDM file");
|
|
||||||
let mut cells = [[Cell::default(); SIZE]; SIZE];
|
|
||||||
let mut row = 0;
|
|
||||||
let mut col = 0;
|
|
||||||
for c in data.chars() {
|
|
||||||
if col == SIZE {
|
|
||||||
col = 0;
|
|
||||||
row += 1;
|
|
||||||
}
|
|
||||||
if let Some(v) = c.to_digit(10) {
|
|
||||||
let value = v as u8;
|
|
||||||
cells[row][col] = Cell {
|
|
||||||
value,
|
|
||||||
loaded: value != 0,
|
|
||||||
invalid: false,
|
|
||||||
};
|
|
||||||
col += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
|
||||||
cells,
|
|
||||||
completed: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn validate(&mut self, ind: [usize; 2], val: u8) {
|
|
||||||
let [b, a] = ind;
|
|
||||||
for i in 0..SIZE {
|
|
||||||
if i == a {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if self.cells[a][i].value == val {
|
|
||||||
self.cells[a][b].invalid = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i in 0..SIZE {
|
|
||||||
if i == b {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if self.cells[i][b].value == val {
|
|
||||||
self.cells[a][b].invalid = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let (row, col) = (a / 3, b / 3);
|
|
||||||
for i in 3 * row..3 * row + 3 {
|
|
||||||
for j in 3 * col..3 * col + 3 {
|
|
||||||
if i == a && j == b {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if self.cells[i][j].value == val {
|
|
||||||
self.cells[a][b].invalid = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.cells[a][b].invalid = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn load_sdm() {
|
|
||||||
let got = Gameboard::load_sdm("static/puzzle.sdm");
|
|
||||||
let want = Gameboard::from_cells([
|
|
||||||
[0, 1, 6, 4, 0, 0, 0, 0, 0],
|
|
||||||
[2, 0, 0, 0, 0, 9, 0, 0, 0],
|
|
||||||
[4, 0, 0, 0, 0, 0, 0, 6, 2],
|
|
||||||
[0, 7, 0, 2, 3, 0, 1, 0, 0],
|
|
||||||
[1, 0, 0, 0, 0, 0, 0, 0, 3],
|
|
||||||
[0, 0, 3, 0, 8, 7, 0, 4, 0],
|
|
||||||
[9, 6, 0, 0, 0, 0, 0, 0, 5],
|
|
||||||
[0, 0, 0, 8, 0, 0, 0, 0, 7],
|
|
||||||
[0, 0, 0, 0, 0, 6, 8, 2, 0],
|
|
||||||
]);
|
|
||||||
assert_eq!(got, want);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
//! Gameboard controller
|
|
||||||
|
|
||||||
use piston::GenericEvent;
|
|
||||||
|
|
||||||
use crate::Gameboard;
|
|
||||||
|
|
||||||
pub struct GameboardController {
|
|
||||||
pub gameboard: Gameboard,
|
|
||||||
pub selected_cell: Option<[usize; 2]>,
|
|
||||||
cursor_pos: [f64; 2],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GameboardController {
|
|
||||||
pub fn new(gameboard: Gameboard) -> GameboardController {
|
|
||||||
GameboardController {
|
|
||||||
gameboard: gameboard,
|
|
||||||
selected_cell: None,
|
|
||||||
cursor_pos: [0.0; 2],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn event<E: GenericEvent>(&mut self, pos: [f64; 2], size: f64, e: &E) {
|
|
||||||
use piston::input::{Button, Key, MouseButton};
|
|
||||||
|
|
||||||
if let Some(pos) = e.mouse_cursor_args() {
|
|
||||||
self.cursor_pos = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(Button::Mouse(MouseButton::Left)) = e.press_args() {
|
|
||||||
let x = self.cursor_pos[0] - pos[0];
|
|
||||||
let y = self.cursor_pos[1] - pos[1];
|
|
||||||
|
|
||||||
if x >= 0.0 && x < size && y >= 0.0 && y < size {
|
|
||||||
let cell_x = (x / size * 9.0) as usize;
|
|
||||||
let cell_y = (y / size * 9.0) as usize;
|
|
||||||
self.selected_cell = Some([cell_x, cell_y]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(Button::Keyboard(key)) = e.press_args() {
|
|
||||||
if let Some(ind) = self.selected_cell {
|
|
||||||
match key {
|
|
||||||
Key::D1 => self.gameboard.set(ind, 1),
|
|
||||||
Key::D2 => self.gameboard.set(ind, 2),
|
|
||||||
Key::D3 => self.gameboard.set(ind, 3),
|
|
||||||
Key::D4 => self.gameboard.set(ind, 4),
|
|
||||||
Key::D5 => self.gameboard.set(ind, 5),
|
|
||||||
Key::D6 => self.gameboard.set(ind, 6),
|
|
||||||
Key::D7 => self.gameboard.set(ind, 7),
|
|
||||||
Key::D8 => self.gameboard.set(ind, 8),
|
|
||||||
Key::D9 => self.gameboard.set(ind, 9),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,210 +0,0 @@
|
|||||||
//! Gameboard view.
|
|
||||||
|
|
||||||
use graphics::character::CharacterCache;
|
|
||||||
use graphics::types::Color;
|
|
||||||
use graphics::{Context, Graphics};
|
|
||||||
|
|
||||||
use crate::gameboard_controller::GameboardController;
|
|
||||||
|
|
||||||
pub struct GameboardViewSettings {
|
|
||||||
pub position: [f64; 2],
|
|
||||||
pub size: f64,
|
|
||||||
pub background_color: Color,
|
|
||||||
pub border_color: Color,
|
|
||||||
pub board_edge_color: Color,
|
|
||||||
pub section_edge_color: Color,
|
|
||||||
pub cell_edge_color: Color,
|
|
||||||
pub board_edge_radius: f64,
|
|
||||||
pub section_edge_radius: f64,
|
|
||||||
pub cell_edge_radius: f64,
|
|
||||||
pub selected_cell_background_color: Color,
|
|
||||||
pub text_color: Color,
|
|
||||||
pub loaded_cell_background_color: Color,
|
|
||||||
pub invalid_cell_background_color: Color,
|
|
||||||
pub invalid_selected_cell_background_color: Color,
|
|
||||||
pub completed_background_color: Color,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GameboardViewSettings {
|
|
||||||
pub fn new() -> GameboardViewSettings {
|
|
||||||
GameboardViewSettings {
|
|
||||||
position: [10.0; 2],
|
|
||||||
size: 400.0,
|
|
||||||
background_color: [0.8, 0.8, 1.0, 1.0],
|
|
||||||
border_color: [0.0, 0.0, 0.2, 1.0],
|
|
||||||
board_edge_color: [0.0, 0.0, 0.2, 1.0],
|
|
||||||
section_edge_color: [0.0, 0.0, 0.2, 1.0],
|
|
||||||
cell_edge_color: [0.0, 0.0, 0.2, 1.0],
|
|
||||||
board_edge_radius: 3.0,
|
|
||||||
section_edge_radius: 2.0,
|
|
||||||
cell_edge_radius: 1.0,
|
|
||||||
selected_cell_background_color: [0.9, 0.9, 1.0, 1.0],
|
|
||||||
text_color: [0.0, 0.0, 0.1, 1.0],
|
|
||||||
loaded_cell_background_color: [1.0, 1.0, 1.0, 1.0],
|
|
||||||
invalid_cell_background_color: [1.0, 0.0, 0.0, 1.0],
|
|
||||||
invalid_selected_cell_background_color: [1.0, 0.0, 0.5, 1.0],
|
|
||||||
completed_background_color: [0.0, 1.0, 0.0, 1.0],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct GameboardView {
|
|
||||||
pub settings: GameboardViewSettings,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GameboardView {
|
|
||||||
pub fn new(settings: GameboardViewSettings) -> GameboardView {
|
|
||||||
GameboardView { settings: settings }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn draw<G: Graphics, C>(
|
|
||||||
&self,
|
|
||||||
controller: &GameboardController,
|
|
||||||
glyphs: &mut C,
|
|
||||||
c: &Context,
|
|
||||||
g: &mut G,
|
|
||||||
) where
|
|
||||||
C: CharacterCache<Texture = G::Texture>,
|
|
||||||
{
|
|
||||||
use graphics::{Image, Line, Rectangle, Transformed};
|
|
||||||
|
|
||||||
let ref settings = self.settings;
|
|
||||||
let board_rect = [
|
|
||||||
settings.position[0],
|
|
||||||
settings.position[1],
|
|
||||||
settings.size,
|
|
||||||
settings.size,
|
|
||||||
];
|
|
||||||
|
|
||||||
if controller.gameboard.completed {
|
|
||||||
Rectangle::new(settings.completed_background_color).draw(
|
|
||||||
board_rect,
|
|
||||||
&c.draw_state,
|
|
||||||
c.transform,
|
|
||||||
g,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
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,
|
|
||||||
);
|
|
||||||
} else if controller.gameboard.cells[i][j].invalid {
|
|
||||||
color_cell(
|
|
||||||
settings,
|
|
||||||
[j, i],
|
|
||||||
settings.invalid_cell_background_color,
|
|
||||||
c,
|
|
||||||
g,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ind) = controller.selected_cell {
|
|
||||||
let cell = controller.gameboard.cells[ind[1]][ind[0]];
|
|
||||||
let color = if !cell.loaded {
|
|
||||||
if !cell.invalid {
|
|
||||||
settings.selected_cell_background_color
|
|
||||||
} else {
|
|
||||||
settings.invalid_selected_cell_background_color
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
settings.loaded_cell_background_color
|
|
||||||
};
|
|
||||||
color_cell(settings, ind, color, c, g);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let text_image = Image::new_color(settings.text_color);
|
|
||||||
let cell_size = settings.size / 9.0;
|
|
||||||
|
|
||||||
for j in 0..9 {
|
|
||||||
for i in 0..9 {
|
|
||||||
if let Some(ch) = controller.gameboard.char([i, j]) {
|
|
||||||
let pos = [
|
|
||||||
settings.position[0] + i as f64 * cell_size + 15.0,
|
|
||||||
settings.position[1] + j as f64 * cell_size + 34.0,
|
|
||||||
];
|
|
||||||
|
|
||||||
if let Ok(character) = glyphs.character(34, ch) {
|
|
||||||
let ch_x = pos[0] + character.left();
|
|
||||||
let ch_y = pos[1] - character.top();
|
|
||||||
let text_image = text_image.src_rect([
|
|
||||||
character.atlas_offset[0],
|
|
||||||
character.atlas_offset[1],
|
|
||||||
character.atlas_size[0],
|
|
||||||
character.atlas_size[1],
|
|
||||||
]);
|
|
||||||
text_image.draw(
|
|
||||||
character.texture,
|
|
||||||
&c.draw_state,
|
|
||||||
c.transform.trans(ch_x, ch_y),
|
|
||||||
g,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let cell_edge = Line::new(settings.cell_edge_color, settings.cell_edge_radius);
|
|
||||||
let section_edge = Line::new(settings.section_edge_color, settings.section_edge_radius);
|
|
||||||
|
|
||||||
for i in 0..9 {
|
|
||||||
let x = settings.position[0] + i as f64 / 9.0 * settings.size;
|
|
||||||
let y = settings.position[1] + i as f64 / 9.0 * settings.size;
|
|
||||||
let x2 = settings.position[0] + settings.size;
|
|
||||||
let y2 = settings.position[1] + settings.size;
|
|
||||||
|
|
||||||
let vline = [x, settings.position[1], x, y2];
|
|
||||||
let hline = [settings.position[0], y, x2, y];
|
|
||||||
|
|
||||||
if (i % 3) == 0 {
|
|
||||||
section_edge.draw(vline, &c.draw_state, c.transform, g);
|
|
||||||
section_edge.draw(hline, &c.draw_state, c.transform, g);
|
|
||||||
} else {
|
|
||||||
cell_edge.draw(vline, &c.draw_state, c.transform, g);
|
|
||||||
cell_edge.draw(hline, &c.draw_state, c.transform, g);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle::new_border(settings.board_edge_color, settings.board_edge_radius).draw(
|
|
||||||
board_rect,
|
|
||||||
&c.draw_state,
|
|
||||||
c.transform,
|
|
||||||
g,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
//////#![deny(missing_docs)]
|
|
||||||
|
|
||||||
//! An Sudoko please.
|
|
||||||
|
|
||||||
extern crate glutin_window;
|
|
||||||
|
|
||||||
use glutin_window::GlutinWindow;
|
|
||||||
use opengl_graphics::{Filter, GlGraphics, GlyphCache, OpenGL, TextureSettings};
|
|
||||||
use piston::event_loop::{EventSettings, Events};
|
|
||||||
use piston::{EventLoop, RenderEvent, WindowSettings};
|
|
||||||
|
|
||||||
pub use crate::gameboard::Gameboard;
|
|
||||||
pub use crate::gameboard_controller::GameboardController;
|
|
||||||
pub use crate::gameboard_view::{GameboardView, GameboardViewSettings};
|
|
||||||
|
|
||||||
mod gameboard;
|
|
||||||
mod gameboard_controller;
|
|
||||||
mod gameboard_view;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let opengl = OpenGL::V3_2;
|
|
||||||
let settings = WindowSettings::new("Sudoku", (640, 480))
|
|
||||||
.exit_on_esc(true)
|
|
||||||
.graphics_api(opengl)
|
|
||||||
.vsync(true);
|
|
||||||
let mut window: GlutinWindow = settings.build().expect("could not create window");
|
|
||||||
let mut events = Events::new(EventSettings::new().lazy(true));
|
|
||||||
let mut gl = GlGraphics::new(opengl);
|
|
||||||
|
|
||||||
let args: Vec<_> = std::env::args().collect();
|
|
||||||
let infile = args.get(1).expect("usage: sudoku <sdm-file>");
|
|
||||||
|
|
||||||
let gameboard = Gameboard::load_sdm(infile);
|
|
||||||
let mut gameboard_controller = GameboardController::new(gameboard);
|
|
||||||
let gameboard_view_settings = GameboardViewSettings::new();
|
|
||||||
let gameboard_view = GameboardView::new(gameboard_view_settings);
|
|
||||||
|
|
||||||
let texture_settings = TextureSettings::new().filter(Filter::Nearest);
|
|
||||||
let ref mut glyphs = GlyphCache::new("assets/FiraSans-Regular.ttf", (), texture_settings)
|
|
||||||
.expect("Could not load font");
|
|
||||||
|
|
||||||
while let Some(e) = events.next(&mut window) {
|
|
||||||
gameboard_controller.event(
|
|
||||||
gameboard_view.settings.position,
|
|
||||||
gameboard_view.settings.size,
|
|
||||||
&e,
|
|
||||||
);
|
|
||||||
if let Some(args) = e.render_args() {
|
|
||||||
gl.draw(args.viewport(), |c, g| {
|
|
||||||
use graphics::clear;
|
|
||||||
|
|
||||||
clear([1.0; 4], g);
|
|
||||||
gameboard_view.draw(&gameboard_controller, glyphs, &c, g);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
517962483236847915498351762371695248654218397829734156765129834142583679983476520
|
|
@ -1 +0,0 @@
|
|||||||
016400000200009000400000062070230100100000003003087040960000005000800007000006820
|
|
Loading…
x
Reference in New Issue
Block a user