sudoku solver can basically be a backtracking algorithm . Last month I implemented a Rat-Maze problem solver with Yew App. But it does not look visually much attractive to some of my friends. So thought of doing a sudoku solver with same code modifying the logic for sudoku.
Demo video
if you are interested to see the code, it here ( Note: its an ugly code)
Writing code in Rust programming language is always fun and a learning.So thought of making some enhancements to the yew app
1. add colors to the cells
2. after solving the path, change the color of the cells in the path. ..etc
This gave an opportunity to work with CSS and Yew. I think still there is no full support for CSS from Yew as you might have seen in React. But I was managed to change the color with "class" property in CSS.
Solving this problem in Rust programming will be a little more interesting. Even more fun if we can build this as Rust Wasm app. Webassembly (wasm) is one of the latest technology that web developers are interested in. So thought of building the rat-maze as a Yew app.
Yew is a modern Rust framework for creating multi-threaded front-end web apps with WebAssembly
It was not that hard to write a function and build for wasm target. I was using the #![no_std] without knowing much on it.The Rust compiler was just guiding through errors to fill the code.
I did not use the wasmbind-gen. But I did use wee_alloc
The program is below:
Note: just comment each line and see the error message compiler is giving to you.
How nice it would be if I can call my own created C programs especially the computational intensive C programs from my Mozilla or Google Browser ( :-) in fact I don’t have anything that much computational intensive), But still . I would also be amazed if I can port some of the C libraries or C++ Games to browser.
Emscripten and Webassembly(wasm) together make this happen
I was following web-assembly and Rust for a few months now. Since Rust has lot of safety features, I did not think of exploring more on porting C or C++ programs to browser.
Emscripten is an Open Source LLVM to JavaScript compiler. Using Emscripten you can:
Compile C and C++ code into JavaScript
Compile any other code that can be translated into LLVM bitcode into JavaScript.
Compile the C/C++ runtimes of other languages into JavaScript, and then run code in those other languages in an indirect way (this has been done for Python and Lua)!
WebAssembly (often shortened to Wasm) is an open standard that defines a portable binary code format for executable programs, and a corresponding textual assembly language, as well as interfaces for facilitating interactions between such programs and their host environment.
Emscripten Installation
Emcripten is not that complex to install,there is good documentation in the site - Emscripten
You might need to install python2.7 and cmake etc as a prior requisite.We just need to follow the instructions. My Linux machine helped me to install everything with apt-get insall command.
You might come across some installation errors, but just search those errors in google, there will be solution to fix it.
C program to wasm
I wrote a simple C program called emccwasm.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdint.h>
int main(){
int a = 1;
printf("%d",a);
//string function to put a space in the screen
puts(" ");
printf("First C program compiled to browser. a=%d",a);
return 1;
}
In command line, you might need to use below command to compile if you are using Linux machine. emcc -s NO_EXIT_RUNTIME=1 -s FORCE_FILESYSTEM=1 -s EXPORTED_FUNCTIONS=[’_main’] -o emccwasm.html emccwasm.c
Emscripten FAQ might help you understand these options and resolve the errors you might encounter quickly.
The above command generated 3 files for me , they are emccwasm.html , emccwasm.js and emccwasm.wasm
Emscripten generated Files.
Emcripten created a compiled webassembly file which is emccwasm.wasm as mentioned earlier.Filename will be same as the C program file name. To know more about webassembly , following documentation link helps - https://webassembly.org/
In a nutshell “WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server application”
The .js and .html files are glue files created for web. The html file can be rendered to the browser and Javascript file initialize webassembly and rest of the glue work
http server
You might need to install http server to void below error . The following documentation can be used for installation - https://github.com/thecoshman/http
Note: if you have installed Cargo in your machine, the server installation will be very easy.
"**Failed to execute ‘compile’ on ‘WebAssembly’: Incorrect response MIME type. Expected ‘application/wasm’.
**
We can run the server simply by below command:
http
Emscripten files in localhost
Once the http server is up, the files will be served in the browser in the link: http://localhost:8000/emccwasm.html
Note: the port might vary .
If everything goes well, you should be getting a screen similar to below.
Accessing exported functions.
When we compiled the C program we used EXPORT_FUNCTIONS option with _main. That means the _main function should be available in Module.
ie , we can invoke main function by Module._main()
I was reading more on the WebAssembly last week.wrote about JavaScript in the last post, I don't know whether I have given wrong feeling that we should not study JavaScript at all. I did not meant that.In fact we should study JavaScript to understand more on the internals and browser JS engines .
The only thing I meant , we are in need finding alternative ways for more robust/new languages to replace JS drawbacks.
Web Assembly + Rust can offer some of the replacement for JS drawbacks. read more https://webassembly.org/
I don't know I know good enough to write this post, but still writing..
fn using_web_sys()-> Result<(),JsValue>{ use web_sys::console; console::log_1(&"Hellowrld to console using websys".into()); let window = web_sys::window().expect("no global window exists"); let document = window.document().expect("no document found");
let body = document.body().expect("document should have a body");
let val = document.create_element("p")?; val.set_inner_html("Hello from 121Rust!"); val.set_attribute("id","p1"); body.append_child(&val);
let element = document .get_element_by_id("p2").expect("no p2 element found");
let element1 = document .get_element_by_id("p1").expect("no p1 element found");
let att = element.text_content().expect("no element text found");
let att1 = element1.text_content().expect("no element text found"); console::log_1(&att.into()); console::log_1(&att1.into()); Ok(())
}
cargo.toml:
[package]
name = "na-rust-web"
version = "0.1.0"
authors = ["naveen "]
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
cfg-if = "0.1.2"
wasm-bindgen = "0.2.29"
#web-sys = { version = "0.3.6", features = ['console'] }
# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
# code size when deploying.
console_error_panic_hook = { version = "0.1.1", optional = true }
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
# compared to the default allocator's ~10K. It is slower than the default
# allocator, however.
#
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
wee_alloc = { version = "0.4.2", optional = true }
[dev-dependencies]
wasm-bindgen-test = "0.2.29"
[dependencies.web-sys]
version = "0.3.4"
features = [
'Document',
'Element',
'HtmlElement',
'Node',
'Window',
'console',
]
profile.release]
# Tell `rustc` to optimize for small code size.