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

View File

@ -188,7 +188,7 @@ async fn main()
for asset in [
"promote.svg",
"omen_dawn.svg",
"heart_dawn.svg",
"behemoth_dawn.svg",
"dragon_dawn.svg",
"castle_dawn.svg",
@ -197,7 +197,7 @@ async fn main()
"knight_dawn.svg",
"militia_dawn.svg",
"omen_dusk.svg",
"heart_dusk.svg",
"behemoth_dusk.svg",
"dragon_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) {
let mut valid = match request.game_state {
1 => !session.game.complete,
2 => !session.game.complete,
3 => session.game.complete,
1 => !session.game.is_complete(),
2 => !session.game.is_complete(),
3 => session.game.is_complete(),
_ => true,
};
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 !session.game.complete {
if !session.game.is_complete() {
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) {
@ -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(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)
|| (user_id == Some(session.p_dusk.user) && session.game.turn & 1 == 1) {

View File

@ -8,7 +8,7 @@
version="1.1"
id="svg1"
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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
@ -75,9 +75,9 @@
sodipodi:nodetypes="ccccccccccccccc" />
<path
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"
sodipodi:nodetypes="ccccccccc" />
sodipodi:nodetypes="ccccccccccc" />
<path
style="fill:#ffe082;fill-opacity:1"
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.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
@ -170,7 +170,7 @@ GAME.PieceMovement = class {
constructor() {
this.direction = 0;
this.stride = 0;
this.alt = false;
this.alt = 0;
}
add(direction) {
@ -184,8 +184,8 @@ GAME.PieceMovement = class {
return this;
}
add_alt() {
this.alt = true;
add_alt(id) {
this.alt = id;
return this;
}
@ -353,6 +353,8 @@ GAME.Game = class {
piece.tile = play.to;
this.board.tiles[play.from].piece = null;
let moves = piece.moves();
let target_id = this.board.tiles[play.to].piece;
if(target_id !== null) {
let target = this.board.pieces[target_id];
@ -388,8 +390,8 @@ GAME.Game = class {
// Handle alt moves.
if(play.source == 3) {
switch(piece.piece) {
case GAME.Const.PieceId.Knight: {
switch(moves.alt) {
case 0: {
piece.promoted = false;
} break;
}
@ -471,7 +473,7 @@ GAME.Game = class {
let check_direct = (this.state.check & 0x040) != 0;
let check_count = this.state.check & 0x3F;
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(target_id !== null) {
if(check_count > 1) {
@ -487,7 +489,7 @@ GAME.Game = class {
}
// 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;
}
@ -512,7 +514,7 @@ GAME.Game = class {
// Target piece is opposing.
else {
// Check if target piece is opposing king.
if(target.piece == GAME.Const.PieceId.Source) {
if(target.piece == GAME.Const.PieceId.Heart) {
if(valid) {
if(dist == 1) { check = GAME.Const.Check.Direct; }
else { check = GAME.Const.Check.Stride; }
@ -543,7 +545,7 @@ GAME.Game = class {
// Handle blocking restrictions.
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);
} else {
result = result && ((dir_mask & block_directions) != 0 || swap);
@ -570,7 +572,7 @@ GAME.Game = class {
// King cannot swap onto tile that is threatened.
// 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)) {
return false;
}
@ -584,9 +586,12 @@ GAME.Game = class {
let hex = this.board.tiles[piece.tile].hex;
let block_directions = piece.blocking | BITWISE.rotate_blocks6(piece.blocking);
switch(piece.piece) {
case GAME.Const.PieceId.Knight: {
let moves = piece.moves();
switch(moves.alt) {
/* Drop Once */ case 1:
/* Drop Cone */ case 2:
{
// Check all tiles if not blocking.
if(block_directions == 0) {
for(let i = 0; i < GAME_DATA.board.tiles.length; ++i) {
@ -615,7 +620,7 @@ GAME.Game = class {
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));
}
} else { break; }
@ -626,7 +631,7 @@ GAME.Game = class {
}
} break;
case GAME.Const.PieceId.Castle: {
case 3: {
// Check all tiles if not blocking.
if(block_directions == 0) {
@ -718,7 +723,7 @@ GAME.Game = class {
return tiles;
}
placable_tile(piece, tile_id) {
placable_tile(piece, tile_id, params={}) {
let valid = false;
let hex = HEX.tile_to_hex(tile_id);
@ -753,11 +758,13 @@ GAME.Game = class {
// Check if position puts king in check.
let checking = false;
let movements = this.movement_tiles(piece, tile_id, true);
for(let movement of movements) {
if(movement.check) {
checking = true;
break;
if(params.check !== false) {
let movements = this.movement_tiles(piece, tile_id, true);
for(let movement of movements) {
if(movement.check) {
checking = true;
break;
}
}
}
@ -817,7 +824,7 @@ GAME.Const = {
Castle: 4,
Dragon: 5,
Behemoth: 6,
Source: 7,
Heart: 7,
},
Count: {
@ -874,7 +881,7 @@ GAME.Const = {
.add(14)
.add(16)
.add(17)
.add_alt(),
.add_alt(1),
),
new GAME.GamePiece(
"Tower",
@ -916,7 +923,7 @@ GAME.Const = {
.add(5)
.add(7)
.add(10)
.add_alt(),
.add_alt(2),
),
new GAME.GamePiece(
"Dragon",
@ -965,7 +972,7 @@ GAME.Const = {
.add(17)
),
new GAME.GamePiece(
"Source",
"Heart",
new GAME.PieceMovement()
.add(0)
.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/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/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", "受け入れ" ),
decline: new LANGUAGE.Term( "Decline", "断る" ),
play: new LANGUAGE.Term( "Play", "遣る" ),
play: new LANGUAGE.Term( "Play", "続く" ),
check: new LANGUAGE.Term( "Check", "王手" ),
checkmate: new LANGUAGE.Term( "Checkmate", "詰み" ),
@ -76,7 +76,7 @@ LANGUAGE.Terms = {
Castle: new LANGUAGE.Term( "Castle", "城" ),
Dragon: new LANGUAGE.Term( "Dragon", "竜" ),
Behemoth: new LANGUAGE.Term( "Behemoth", "獣" ),
Source: new LANGUAGE.Term( "Source", "元" ),
Heart: new LANGUAGE.Term( "Heart", "元" ),
//: new LANGUAGE.Term( "", "" ),

View File

@ -649,7 +649,7 @@ const SCENES = {
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_prev(); }),
ind_turn,