diff --git a/web/chess/Cargo.toml b/web/chess/Cargo.toml new file mode 100644 index 0000000..3ff2042 --- /dev/null +++ b/web/chess/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "chess" +version = "0.1.0" +edition = "2021" + +[dependencies] +wasm-bindgen = "0.2.95" + +[lib] +crate-type = ["cdylib", "rlib"] diff --git a/web/chess/src/App.tsx b/web/chess/src/App.tsx new file mode 100644 index 0000000..a81a753 --- /dev/null +++ b/web/chess/src/App.tsx @@ -0,0 +1,29 @@ +import React, { useEffect, useState } from 'react'; +import init, { ChessGame } from '../pkg'; // 确保路径正确 + +const App: React.FC = () => { + + + useEffect(() => { + const loadWasm = async () => { + try { + await init() // 初始化 WASM 模块 + const chessboard= ChessGame.new(5*60) + console.log(chessboard.render()) + + } catch (error) { + console.error("Failed to load WASM module:", error); + } + }; + + loadWasm(); + }, []); + + return ( +
+

WASM Module Loaded

+
+ ); +}; + +export default App; diff --git a/web/chess/src/index.css b/web/chess/src/index.css new file mode 100644 index 0000000..6119ad9 --- /dev/null +++ b/web/chess/src/index.css @@ -0,0 +1,68 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/web/chess/src/lib.rs b/web/chess/src/lib.rs new file mode 100644 index 0000000..c8598a7 --- /dev/null +++ b/web/chess/src/lib.rs @@ -0,0 +1,130 @@ +use std::fmt; +use std::collections::HashMap; +use wasm_bindgen::prelude::*; + + +enum Grade { + King, + Queen, + Rook, + Bishop, + Knight, + Pawn, + None +} + +impl Grade { + fn as_str(&self) -> &'static str { + match self { + Grade::King => "king", + Grade::Queen => "queen", + Grade::Rook => "rook", + Grade::Bishop => "bishop", + Grade::Knight => "knight", + Grade::Pawn => "pawn", + Grade::None => "None" + } + } +} + +#[derive(Hash, Eq, PartialEq)] +enum Camp { + Black, + White, +} + +impl Camp { + fn as_str(&self) -> &'static str { + match self { + Camp::Black => "black", + Camp::White => "white", + } + } +} + +struct Chessman { + grade: Grade, + camp: Camp, +} + +struct Player { + username: String, + time:u32, + score:u32 +} + +#[wasm_bindgen] +pub struct ChessGame { + players: HashMap, + chess: Vec, +} + +impl fmt::Display for ChessGame { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + for line in self.chess.as_slice().chunks(8) { + for square in line { + write!(f, " ")?; + match square.camp { + Camp::White => { + match &square.grade { + Grade::King => { write!(f, "♔")?; } + Grade::Queen => { write!(f, "♕")?; } + Grade::Rook => { write!(f, "♖")?; } + Grade::Bishop => { write!(f, "♗")?; } + Grade::Knight => { write!(f, "♘")?; } + Grade::Pawn => { write!(f, "♙")?; } + Grade::None => { write!(f, "※")?; } + } + } + Camp::Black => { + match &square.grade { + Grade::King => { write!(f, "♚")?; } + Grade::Queen => { write!(f, "♛")?; } + Grade::Rook => { write!(f, "♜")?; } + Grade::Bishop => { write!(f, "♝")?; } + Grade::Knight => { write!(f, "♞")?; } + Grade::Pawn => { write!(f, "♟")?; } + Grade::None => { write!(f, "※")?; } + } + } + } + } + write!(f, "\n")?; + } + Ok(()) + } +} + +#[wasm_bindgen] +impl ChessGame { + pub fn new(time:u32) -> ChessGame { + fn level_position(index: u8) -> Grade { + match index { + 0 | 7 => Grade::Rook, + 1 | 6 => Grade::Knight, + 2 | 5 => Grade::Bishop, + 3 => Grade::King, + 4 => Grade::Queen, + _ => Grade::None + } + } + let chess_game = (0..64).map(|i| { + let row = i / 8; + let color = if row == 0 || row == 1 { Camp::Black } else { Camp::White }; + if row == 1 || row == 6 { + return Chessman { grade: Grade::Pawn, camp: color } + } else if row == 0 || row == 7 { + return Chessman { grade: level_position(i % 8), camp: color } + } else { + Chessman { grade: Grade::None, camp: color } + } + }).collect(); + let mut players=HashMap::new(); + players.insert(Camp::Black, Player{username:String::from("黑色玩家"), time, score:0 }); + players.insert(Camp::White, Player{username:String::from("白色玩家"), time, score:0 }); + + ChessGame { players, chess: chess_game } + } + pub fn render(&self) -> String { self.to_string() } +} + diff --git a/web/chess/src/main.tsx b/web/chess/src/main.tsx new file mode 100644 index 0000000..0dd7dec --- /dev/null +++ b/web/chess/src/main.tsx @@ -0,0 +1,12 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import WasmComponent from './App.tsx' + +createRoot(document.getElementById('root')!).render( + + + , +) + + +