Update piece names; remove check restriction from alt moves.

This commit is contained in:
yukirij 2024-09-25 18:06:07 -07:00
parent f22f8cde3b
commit 913a35beaa
27 changed files with 91 additions and 44 deletions

View File

@ -5,10 +5,20 @@ use crate::{
piece::Piece, util::Hex, piece::Piece, util::Hex,
}; };
#[derive(Clone, Copy)]
enum GameStatus {
Normal,
Check(u32),
Checkmate,
Resign,
}
pub type Pool = [u8; 7]; pub type Pool = [u8; 7];
#[derive(Clone)]
pub struct Game { pub struct Game {
pub complete:bool, status:GameStatus,
pub turn:u16, pub turn:u16,
pub board:Board, pub board:Board,
pub pool:[Pool; 2], pub pool:[Pool; 2],
@ -19,7 +29,7 @@ impl Game {
pub fn new() -> Self pub fn new() -> Self
{ {
Self { Self {
complete:false, status:GameStatus::Normal,
turn:0, turn:0,
@ -48,7 +58,10 @@ impl Game {
{ {
let player = (self.turn & 1) as u8; let player = (self.turn & 1) as u8;
if self.complete { return Err(()); } match self.status {
GameStatus::Checkmate | GameStatus::Resign => { return Err(()); }
_ => { }
}
let valid = true; let valid = true;
@ -133,7 +146,7 @@ impl Game {
// Player retired. // Player retired.
2 => { 2 => {
self.complete = true; self.status = GameStatus::Resign;
true true
} }
@ -149,4 +162,12 @@ impl Game {
{ {
Vec::new() Vec::new()
} }
pub fn is_complete(&self) -> bool
{
match self.status {
GameStatus::Checkmate | GameStatus::Resign => true,
_ => false,
}
}
} }

View File

@ -238,7 +238,7 @@ impl App {
// Add to resume if session has user and is user turn. // Add to resume if session has user and is user turn.
let is_turn_player = (session.p_dawn.user == user_id && (session.game.turn & 1) == 0) || (session.p_dusk.user == user_id && (session.game.turn & 1) == 1); let is_turn_player = (session.p_dawn.user == user_id && (session.game.turn & 1) == 0) || (session.p_dusk.user == user_id && (session.game.turn & 1) == 1);
if !session.game.complete && is_turn_player { if !session.game.is_complete() && is_turn_player {
response.resume += 1; response.resume += 1;
} }

View File

@ -188,7 +188,7 @@ async fn main()
for asset in [ for asset in [
"promote.svg", "promote.svg",
"omen_dawn.svg", "heart_dawn.svg",
"behemoth_dawn.svg", "behemoth_dawn.svg",
"dragon_dawn.svg", "dragon_dawn.svg",
"castle_dawn.svg", "castle_dawn.svg",
@ -197,7 +197,7 @@ async fn main()
"knight_dawn.svg", "knight_dawn.svg",
"militia_dawn.svg", "militia_dawn.svg",
"omen_dusk.svg", "heart_dusk.svg",
"behemoth_dusk.svg", "behemoth_dusk.svg",
"dragon_dusk.svg", "dragon_dusk.svg",
"castle_dusk.svg", "castle_dusk.svg",

View File

@ -362,9 +362,9 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
if let Some(session) = app.sessions.get(token) { if let Some(session) = app.sessions.get(token) {
let mut valid = match request.game_state { let mut valid = match request.game_state {
1 => !session.game.complete, 1 => !session.game.is_complete(),
2 => !session.game.complete, 2 => !session.game.is_complete(),
3 => session.game.complete, 3 => session.game.is_complete(),
_ => true, _ => true,
}; };
valid &= !request.is_player || Some(session.p_dawn.user) == user_id || Some(session.p_dusk.user) == user_id; valid &= !request.is_player || Some(session.p_dawn.user) == user_id || Some(session.p_dusk.user) == user_id;
@ -473,7 +473,7 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
}; };
if let Some(session) = app.sessions.get_mut(&request.token) { if let Some(session) = app.sessions.get_mut(&request.token) {
if !session.game.complete { if !session.game.is_complete() {
if (user_id == Some(session.p_dawn.user) && session.game.turn & 1 == 0) if (user_id == Some(session.p_dawn.user) && session.game.turn & 1 == 0)
|| (user_id == Some(session.p_dusk.user) && session.game.turn & 1 == 1) { || (user_id == Some(session.p_dusk.user) && session.game.turn & 1 == 1) {
@ -548,7 +548,7 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
if let Some(sid) = session_id { if let Some(sid) = session_id {
if let Some(session) = app.sessions.get_mut(&sid) { if let Some(session) = app.sessions.get_mut(&sid) {
if !session.game.complete { if !session.game.is_complete() {
if (user_id == Some(session.p_dawn.user) && session.game.turn & 1 == 0) if (user_id == Some(session.p_dawn.user) && session.game.turn & 1 == 0)
|| (user_id == Some(session.p_dusk.user) && session.game.turn & 1 == 1) { || (user_id == Some(session.p_dusk.user) && session.game.turn & 1 == 1) {

View File

@ -8,7 +8,7 @@
version="1.1" version="1.1"
id="svg1" id="svg1"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)" inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
sodipodi:docname="king_dawn.svg" sodipodi:docname="heart_dawn.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -75,9 +75,9 @@
sodipodi:nodetypes="ccccccccccccccc" /> sodipodi:nodetypes="ccccccccccccccc" />
<path <path
style="fill:#ffe082;fill-opacity:1" style="fill:#ffe082;fill-opacity:1"
d="M 50,40 60,50 70,40 75,30 V 25 L 60,15 45,25 v 5 z" d="M 50,40 60,50 70,40 75,30 v -5 l -5,-5 -10,-5 -10,5 -5,5 v 5 z"
id="path13" id="path13"
sodipodi:nodetypes="ccccccccc" /> sodipodi:nodetypes="ccccccccccc" />
<path <path
style="fill:#ffe082;fill-opacity:1" style="fill:#ffe082;fill-opacity:1"
d="m 35,35 -5,5 5,5 5,-5 z" d="m 35,35 -5,5 5,5 5,-5 z"

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 932 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -40,7 +40,7 @@ GAME.Board = class {
{ piece:GAME.Const.PieceId.Dragon, hex:new MATH.Vec2(4, 2) }, { piece:GAME.Const.PieceId.Dragon, hex:new MATH.Vec2(4, 2) },
{ piece:GAME.Const.PieceId.Behemoth, hex:new MATH.Vec2(4, 1) }, { piece:GAME.Const.PieceId.Behemoth, hex:new MATH.Vec2(4, 1) },
{ piece:GAME.Const.PieceId.Source, hex:new MATH.Vec2(4, 0) }, { piece:GAME.Const.PieceId.Heart, hex:new MATH.Vec2(4, 0) },
]; ];
// Add Dawn pieces // Add Dawn pieces
@ -170,7 +170,7 @@ GAME.PieceMovement = class {
constructor() { constructor() {
this.direction = 0; this.direction = 0;
this.stride = 0; this.stride = 0;
this.alt = false; this.alt = 0;
} }
add(direction) { add(direction) {
@ -184,8 +184,8 @@ GAME.PieceMovement = class {
return this; return this;
} }
add_alt() { add_alt(id) {
this.alt = true; this.alt = id;
return this; return this;
} }
@ -353,6 +353,8 @@ GAME.Game = class {
piece.tile = play.to; piece.tile = play.to;
this.board.tiles[play.from].piece = null; this.board.tiles[play.from].piece = null;
let moves = piece.moves();
let target_id = this.board.tiles[play.to].piece; let target_id = this.board.tiles[play.to].piece;
if(target_id !== null) { if(target_id !== null) {
let target = this.board.pieces[target_id]; let target = this.board.pieces[target_id];
@ -388,8 +390,8 @@ GAME.Game = class {
// Handle alt moves. // Handle alt moves.
if(play.source == 3) { if(play.source == 3) {
switch(piece.piece) { switch(moves.alt) {
case GAME.Const.PieceId.Knight: { case 0: {
piece.promoted = false; piece.promoted = false;
} break; } break;
} }
@ -471,7 +473,7 @@ GAME.Game = class {
let check_direct = (this.state.check & 0x040) != 0; let check_direct = (this.state.check & 0x040) != 0;
let check_count = this.state.check & 0x3F; let check_count = this.state.check & 0x3F;
if(piece.player == (this.turn & 1) && this.state.check != 0) { if(piece.player == (this.turn & 1) && this.state.check != 0) {
if(piece.piece != GAME.Const.PieceId.Source) { if(piece.piece != GAME.Const.PieceId.Heart) {
if(tile_data.checking != 0) { if(tile_data.checking != 0) {
if(target_id !== null) { if(target_id !== null) {
if(check_count > 1) { if(check_count > 1) {
@ -487,7 +489,7 @@ GAME.Game = class {
} }
// King may not move onto threatened tile. // King may not move onto threatened tile.
if(piece.piece == GAME.Const.PieceId.Source && tile_data.threaten[+(!piece.player)] > 0) { if(piece.piece == GAME.Const.PieceId.Heart && tile_data.threaten[+(!piece.player)] > 0) {
result = false; result = false;
} }
@ -512,7 +514,7 @@ GAME.Game = class {
// Target piece is opposing. // Target piece is opposing.
else { else {
// Check if target piece is opposing king. // Check if target piece is opposing king.
if(target.piece == GAME.Const.PieceId.Source) { if(target.piece == GAME.Const.PieceId.Heart) {
if(valid) { if(valid) {
if(dist == 1) { check = GAME.Const.Check.Direct; } if(dist == 1) { check = GAME.Const.Check.Direct; }
else { check = GAME.Const.Check.Stride; } else { check = GAME.Const.Check.Stride; }
@ -543,7 +545,7 @@ GAME.Game = class {
// Handle blocking restrictions. // Handle blocking restrictions.
if(block_directions != 0) { if(block_directions != 0) {
if(piece.piece == GAME.Const.PieceId.Source) { if(piece.piece == GAME.Const.PieceId.Heart) {
result = result && ((dir_mask & block_directions) == 0 || tile_occupied); result = result && ((dir_mask & block_directions) == 0 || tile_occupied);
} else { } else {
result = result && ((dir_mask & block_directions) != 0 || swap); result = result && ((dir_mask & block_directions) != 0 || swap);
@ -570,7 +572,7 @@ GAME.Game = class {
// King cannot swap onto tile that is threatened. // King cannot swap onto tile that is threatened.
// This case should also cover blocking. // This case should also cover blocking.
if(target.piece == GAME.Const.PieceId.Source if(target.piece == GAME.Const.PieceId.Heart
&& (this.board.tiles[tile].threaten[+(!target.player)] > 0 || piece.blocking != 0)) { && (this.board.tiles[tile].threaten[+(!target.player)] > 0 || piece.blocking != 0)) {
return false; return false;
} }
@ -584,9 +586,12 @@ GAME.Game = class {
let hex = this.board.tiles[piece.tile].hex; let hex = this.board.tiles[piece.tile].hex;
let block_directions = piece.blocking | BITWISE.rotate_blocks6(piece.blocking); let block_directions = piece.blocking | BITWISE.rotate_blocks6(piece.blocking);
switch(piece.piece) { let moves = piece.moves();
case GAME.Const.PieceId.Knight: {
switch(moves.alt) {
/* Drop Once */ case 1:
/* Drop Cone */ case 2:
{
// Check all tiles if not blocking. // Check all tiles if not blocking.
if(block_directions == 0) { if(block_directions == 0) {
for(let i = 0; i < GAME_DATA.board.tiles.length; ++i) { for(let i = 0; i < GAME_DATA.board.tiles.length; ++i) {
@ -615,7 +620,7 @@ GAME.Game = class {
if(target_id !== null) { break; } if(target_id !== null) { break; }
if(this.placable_tile(piece, tile_id)) { if(this.placable_tile(piece, tile_id, {check:false})) {
tiles.push(new GAME.MovementTile(tile_id, true, false, 0, 0)); tiles.push(new GAME.MovementTile(tile_id, true, false, 0, 0));
} }
} else { break; } } else { break; }
@ -626,7 +631,7 @@ GAME.Game = class {
} }
} break; } break;
case GAME.Const.PieceId.Castle: { case 3: {
// Check all tiles if not blocking. // Check all tiles if not blocking.
if(block_directions == 0) { if(block_directions == 0) {
@ -718,7 +723,7 @@ GAME.Game = class {
return tiles; return tiles;
} }
placable_tile(piece, tile_id) { placable_tile(piece, tile_id, params={}) {
let valid = false; let valid = false;
let hex = HEX.tile_to_hex(tile_id); let hex = HEX.tile_to_hex(tile_id);
@ -753,6 +758,7 @@ GAME.Game = class {
// Check if position puts king in check. // Check if position puts king in check.
let checking = false; let checking = false;
if(params.check !== false) {
let movements = this.movement_tiles(piece, tile_id, true); let movements = this.movement_tiles(piece, tile_id, true);
for(let movement of movements) { for(let movement of movements) {
if(movement.check) { if(movement.check) {
@ -760,6 +766,7 @@ GAME.Game = class {
break; break;
} }
} }
}
// Piece must have movements and not put king in check. // Piece must have movements and not put king in check.
if(position_valid && movements.length > 0 && !checking) { if(position_valid && movements.length > 0 && !checking) {
@ -817,7 +824,7 @@ GAME.Const = {
Castle: 4, Castle: 4,
Dragon: 5, Dragon: 5,
Behemoth: 6, Behemoth: 6,
Source: 7, Heart: 7,
}, },
Count: { Count: {
@ -874,7 +881,7 @@ GAME.Const = {
.add(14) .add(14)
.add(16) .add(16)
.add(17) .add(17)
.add_alt(), .add_alt(1),
), ),
new GAME.GamePiece( new GAME.GamePiece(
"Tower", "Tower",
@ -916,7 +923,7 @@ GAME.Const = {
.add(5) .add(5)
.add(7) .add(7)
.add(10) .add(10)
.add_alt(), .add_alt(2),
), ),
new GAME.GamePiece( new GAME.GamePiece(
"Dragon", "Dragon",
@ -965,7 +972,7 @@ GAME.Const = {
.add(17) .add(17)
), ),
new GAME.GamePiece( new GAME.GamePiece(
"Source", "Heart",
new GAME.PieceMovement() new GAME.PieceMovement()
.add(0) .add(0)
.add(1) .add(1)

View File

@ -16,6 +16,6 @@ GAME_ASSET.Image = {
[ GAME_ASSET.load_image("/asset/castle_dawn.svg"), GAME_ASSET.load_image("/asset/castle_dusk.svg") ], [ GAME_ASSET.load_image("/asset/castle_dawn.svg"), GAME_ASSET.load_image("/asset/castle_dusk.svg") ],
[ GAME_ASSET.load_image("/asset/dragon_dawn.svg"), GAME_ASSET.load_image("/asset/dragon_dusk.svg") ], [ GAME_ASSET.load_image("/asset/dragon_dawn.svg"), GAME_ASSET.load_image("/asset/dragon_dusk.svg") ],
[ GAME_ASSET.load_image("/asset/behemoth_dawn.svg"), GAME_ASSET.load_image("/asset/behemoth_dusk.svg") ], [ GAME_ASSET.load_image("/asset/behemoth_dawn.svg"), GAME_ASSET.load_image("/asset/behemoth_dusk.svg") ],
[ GAME_ASSET.load_image("/asset/omen_dawn.svg"), GAME_ASSET.load_image("/asset/omen_dusk.svg") ], [ GAME_ASSET.load_image("/asset/heart_dawn.svg"), GAME_ASSET.load_image("/asset/heart_dusk.svg") ],
], ],
}; };

19
www/js/game_config.js Normal file
View File

@ -0,0 +1,19 @@
class GameConfig {
constructor() {
this.key = new Uint8Array(4);
this.name = "";
//this.user = 0;
this.pieces = [ ];
this.layout = [ ];
this.pools = new Uint8Array(14);
this.actions = [ ];
this.states = [ ];
}
}
GameConfig.State = class {
//this.name = "";
};

View File

@ -64,7 +64,7 @@ LANGUAGE.Terms = {
accept: new LANGUAGE.Term( "Accept", "受け入れ" ), accept: new LANGUAGE.Term( "Accept", "受け入れ" ),
decline: new LANGUAGE.Term( "Decline", "断る" ), decline: new LANGUAGE.Term( "Decline", "断る" ),
play: new LANGUAGE.Term( "Play", "遣る" ), play: new LANGUAGE.Term( "Play", "続く" ),
check: new LANGUAGE.Term( "Check", "王手" ), check: new LANGUAGE.Term( "Check", "王手" ),
checkmate: new LANGUAGE.Term( "Checkmate", "詰み" ), checkmate: new LANGUAGE.Term( "Checkmate", "詰み" ),
@ -76,7 +76,7 @@ LANGUAGE.Terms = {
Castle: new LANGUAGE.Term( "Castle", "城" ), Castle: new LANGUAGE.Term( "Castle", "城" ),
Dragon: new LANGUAGE.Term( "Dragon", "竜" ), Dragon: new LANGUAGE.Term( "Dragon", "竜" ),
Behemoth: new LANGUAGE.Term( "Behemoth", "獣" ), Behemoth: new LANGUAGE.Term( "Behemoth", "獣" ),
Source: new LANGUAGE.Term( "Source", "元" ), Heart: new LANGUAGE.Term( "Heart", "元" ),
//: new LANGUAGE.Term( "", "" ), //: new LANGUAGE.Term( "", "" ),

View File

@ -649,7 +649,7 @@ const SCENES = {
UI.mainnav( UI.mainnav(
[ ], [ ],
[ [
UI.button("Auto", () => { INTERFACE.replay_toggle_auto(); }), UI.button(LANG("auto"), () => { INTERFACE.replay_toggle_auto(); }),
UI.button("◀", () => { INTERFACE.replay_off(); INTERFACE.replay_first(); }), UI.button("◀", () => { INTERFACE.replay_off(); INTERFACE.replay_first(); }),
UI.button("◁", () => { INTERFACE.replay_off(); INTERFACE.replay_prev(); }), UI.button("◁", () => { INTERFACE.replay_off(); INTERFACE.replay_prev(); }),
ind_turn, ind_turn,