diff --git a/www/js/game.js b/www/js/game.js index 766f48a..be64e80 100644 --- a/www/js/game.js +++ b/www/js/game.js @@ -242,7 +242,7 @@ GAME.Game = class { this.state.check = 0; this.state.checkmate = false; - let player = this.turn & 1; + let player = (this.turn + this.config.rules.reverse) & 1; // Determine threaten, check, and blocking for each piece let checking_pieces = 0; @@ -318,7 +318,7 @@ GAME.Game = class { let player = 0; if(play.player == -1) { - player = this.turn & 1; + player = (this.turn + this.config.rules.reverse) & 1; } else { player = play.player; } @@ -403,7 +403,7 @@ GAME.Game = class { play_is_valid(play) { let player = 0; if(play.player == -1) { - player = this.turn & 1; + player = (this.turn + this.config.rules.reverse) & 1; } else { player = play.player; } @@ -506,7 +506,7 @@ GAME.Game = class { // Prevent moves that do not uncheck King. 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.player == ((this.turn + this.config.rules.reverse) & 1) && this.state.check != 0) { if(piece.piece != GAME.Const.PieceId.Heart) { if(tile_data.checking) { if(target_id !== null) { @@ -760,7 +760,7 @@ GAME.Game = class { // Prevent placement that does not uncheck King. let check_direct = (this.state.check & GAME.Const.Check.Direct) != 0; let check_count = this.state.check & 0x3F; - if(piece.player == (this.turn & 1) && this.state.check != 0) { + if(piece.player == ((this.turn + this.config.rules.reverse) & 1) && this.state.check != 0) { if(check_direct == 0 && check_count == 1) { position_valid = tile.checking; } else { diff --git a/www/js/game_config.js b/www/js/game_config.js index 814263e..a34ce86 100644 --- a/www/js/game_config.js +++ b/www/js/game_config.js @@ -9,6 +9,7 @@ class GameConfig { this.pool = new Uint8Array(14); this.rules = { + reverse:0, turn:true, }; diff --git a/www/js/game_config_const.js b/www/js/game_config_const.js index ab22668..677d725 100644 --- a/www/js/game_config_const.js +++ b/www/js/game_config_const.js @@ -212,7 +212,8 @@ const GAME_CONFIGS = { .set_layout( new GameConfig.Layout() .add_piece(2, 0, false, new MATH.Vec2(4, 3)) - .add_piece(2, 0, true, new MATH.Vec2(4, 5)) + .add_piece(2, 0, true, new MATH.Vec2(5, 5)) + .add_piece(2, 0, false, new MATH.Vec2(3, 4)) ) .set_pool(CONFIG_POOL_DEMO) .set_rule("turn", false), @@ -248,6 +249,9 @@ const GAME_CONFIGS = { new GameConfig.Layout() .add_piece(5, 0, false, new MATH.Vec2(4, 3)) .add_piece(5, 0, true, new MATH.Vec2(4, 5)) + .add_piece(0, 1, false, new MATH.Vec2(2, 4)) + .add_piece(2, 1, false, new MATH.Vec2(3, 5)) + .add_piece(2, 1, false, new MATH.Vec2(5, 5)) ) .set_pool(CONFIG_POOL_DEMO) .set_rule("turn", false), @@ -276,4 +280,79 @@ const GAME_CONFIGS = { ) .set_pool(CONFIG_POOL_DEMO) .set_rule("turn", false), + + // Drop + Guide_Drop: new GameConfig() + .set_pieces(CONFIG_PIECES_STANDARD) + .set_layout( + new GameConfig.Layout() + .add_piece(7, 0, false, new MATH.Vec2(6, 3)) + .add_piece(0, 0, false, new MATH.Vec2(5, 4)) + .add_piece(0, 0, false, new MATH.Vec2(6, 5)) + .add_piece(0, 0, false, new MATH.Vec2(7, 5)) + .add_piece(1, 0, false, new MATH.Vec2(8, 5)) + .add_piece(0, 0, false, new MATH.Vec2(2, 2)) + .add_piece(0, 1, false, new MATH.Vec2(2, 1)) + .add_piece(3, 1, false, new MATH.Vec2(3, 2)) + .add_piece(2, 0, false, new MATH.Vec2(3, 4)) + .add_piece(0, 1, false, new MATH.Vec2(8, 7)) + .add_piece(7, 1, false, new MATH.Vec2(4, 7)) + .add_piece(4, 1, false, new MATH.Vec2(1, 4)) + .add_piece(0, 1, false, new MATH.Vec2(0, 4)) + ) + .set_pool(CONFIG_POOL_DEMO) + .set_rule("turn", false), + + // Promote + Guide_Promote: new GameConfig() + .set_pieces(CONFIG_PIECES_STANDARD) + .set_layout( + new GameConfig.Layout() + .add_piece(1, 0, false, new MATH.Vec2(0, 0)) + .add_piece(1, 0, false, new MATH.Vec2(8, 4)) + .add_piece(1, 1, false, new MATH.Vec2(0, 4)) + .add_piece(1, 1, false, new MATH.Vec2(8, 8)) + .add_piece(0, 1, false, new MATH.Vec2(8, 7)) + .add_piece(0, 1, false, new MATH.Vec2(7, 7)) + .add_piece(4, 1, false, new MATH.Vec2(2, 6)) + .add_piece(5, 0, false, new MATH.Vec2(4, 2)) + .add_piece(6, 0, false, new MATH.Vec2(4, 4)) + .add_piece(7, 1, false, new MATH.Vec2(3, 6)) + .add_piece(4, 0, false, new MATH.Vec2(6, 7)) + .add_piece(3, 0, false, new MATH.Vec2(5, 6)) + .add_piece(2, 1, false, new MATH.Vec2(6, 3)) + .add_piece(0, 1, false, new MATH.Vec2(3, 1)) + ) + .set_pool(CONFIG_POOL_DEMO) + .set_rule("turn", false), + + // Check + Guide_Check: new GameConfig() + .set_pieces(CONFIG_PIECES_STANDARD) + .set_layout( + new GameConfig.Layout() + .add_piece(7, 0, false, new MATH.Vec2(4, 3)) + .add_piece(4, 0, false, new MATH.Vec2(2, 3)) + .add_piece(5, 0, false, new MATH.Vec2(5, 4)) + .add_piece(0, 1, false, new MATH.Vec2(4, 4)) + .add_piece(2, 1, false, new MATH.Vec2(5, 6)) + ) + .set_pool(CONFIG_POOL_DEMO), + + // Checkmate + Guide_Checkmate: new GameConfig() + .set_pieces(CONFIG_PIECES_STANDARD) + .set_layout( + new GameConfig.Layout() + .add_piece(3, 0, false, new MATH.Vec2(4, 6)) + .add_piece(2, 0, false, new MATH.Vec2(5, 5)) + .add_piece(7, 1, false, new MATH.Vec2(4, 7)) + .add_piece(4, 1, false, new MATH.Vec2(5, 8)) + .add_piece(0, 1, false, new MATH.Vec2(6, 8)) + .add_piece(5, 0, false, new MATH.Vec2(8, 4)) + .add_piece(3, 1, false, new MATH.Vec2(2, 6)) + .add_piece(2, 1, false, new MATH.Vec2(3, 6)) + ) + .set_pool(CONFIG_POOL_DEMO) + .set_rule("reverse", true), }; diff --git a/www/js/interface.js b/www/js/interface.js index 38daefc..66e4729 100644 --- a/www/js/interface.js +++ b/www/js/interface.js @@ -238,7 +238,7 @@ const INTERFACE = { console.log("Select not null"); // Play selection. - if(INTERFACE_DATA.hover.source == 0 && (INTERFACE_DATA.mode == INTERFACE.Mode.Local || (INTERFACE_DATA.player == (GAME_DATA.turn & 1) || !GAME_DATA.config.rules.turn))) { + if(INTERFACE_DATA.hover.source == 0 && (INTERFACE_DATA.mode == INTERFACE.Mode.Local || (INTERFACE_DATA.player == ((GAME_DATA.turn + GAME_DATA.config.rules.reverse) & 1) || !GAME_DATA.config.rules.turn))) { console.log("D1"); let tile_state = INTERFACE_DATA.Game.board_state[INTERFACE_DATA.hover.tile][1]; @@ -253,7 +253,7 @@ const INTERFACE = { pool_selected ^= INTERFACE_DATA.rotate; } - if((GAME_DATA.turn & 1) != pool_selected) { + if(((GAME_DATA.turn + GAME_DATA.config.rules.reverse) & 1) != pool_selected) { if(GAME_DATA.config.rules.turn) { console.log("NOT POOL"); result = 0; @@ -342,7 +342,9 @@ const INTERFACE = { } break; default: { - INTERFACE_DATA.select = null; + if(!event.ctrlKey) { + INTERFACE_DATA.select = null; + } } break; } @@ -362,8 +364,8 @@ const INTERFACE = { }, contextmenu(event) { - INTERFACE_DATA.select = null; if(!event.ctrlKey) { + INTERFACE_DATA.select = null; event.preventDefault(); return false; } else { @@ -442,7 +444,7 @@ const INTERFACE = { switch(INTERFACE_DATA.mode) { case INTERFACE.Mode.Player: { let b_resign = document.getElementById("button-resign"); - if(GAME_DATA.state.code == GAME.Const.State.Normal && (GAME_DATA.turn & 1) == INTERFACE_DATA.player) { + if(GAME_DATA.state.code == GAME.Const.State.Normal && ((GAME_DATA.turn + GAME_DATA.config.rules.reverse) & 1) == INTERFACE_DATA.player) { b_resign.removeAttribute("disabled"); } else { b_resign.setAttribute("disabled", ""); @@ -598,7 +600,7 @@ const INTERFACE = { let is_check = (GAME_DATA.state.check != 0 || GAME_DATA.state.code == GAME.Const.State.Checkmate) && piece !== null && piece.piece == GAME.Const.PieceId.Heart - && piece.player == (GAME_DATA.turn & 1); + && piece.player == ((GAME_DATA.turn + GAME_DATA.config.rules.reverse) & 1); let background_color = null; let border_color = null; @@ -1162,7 +1164,7 @@ const INTERFACE = { } // Draw border - let turn_indicator = !GAME_DATA.config.rules.turn || (player == (GAME_DATA.turn & 1) && (INTERFACE_DATA.player == player || INTERFACE_DATA.player == 2)); + let turn_indicator = !GAME_DATA.config.rules.turn || (player == ((GAME_DATA.turn + GAME_DATA.config.rules.reverse) & 1) && (INTERFACE_DATA.player == player || INTERFACE_DATA.player == 2)); if(is_hover || background_color !== null || turn_indicator) { if(is_hover) { this.ctx.fillStyle = INTERFACE.Color.HintHover; } else { this.ctx.fillStyle = player_color; } @@ -1525,7 +1527,7 @@ const INTERFACE = { case 2: { let piece_id = GAME_DATA.board.tiles[play.from].piece; let piece = GAME_DATA.board.pieces[piece_id]; - valid = piece.player == (GAME_DATA.turn & 1) || !GAME_DATA.config.rules.turn; + valid = piece.player == ((GAME_DATA.turn + GAME_DATA.config.rules.reverse) & 1) || !GAME_DATA.config.rules.turn; } break; case 1: { @@ -1542,7 +1544,7 @@ const INTERFACE = { case INTERFACE.Mode.Local: { INTERFACE.history_push(play, true); - if((INTERFACE_DATA.Game.auto & (1 << (GAME_DATA.turn & 1))) != 0) { + if((INTERFACE_DATA.Game.auto & (1 << ((GAME_DATA.turn + GAME_DATA.config.rules.reverse) & 1))) != 0) { setTimeout(INTERFACE.auto_play, 1000); } } break; @@ -1740,7 +1742,7 @@ const INTERFACE = { }, auto_play() { - let bit = 1 << (GAME_DATA.turn & 1); + let bit = 1 << ((GAME_DATA.turn + GAME_DATA.config.rules.reverse) & 1); if((INTERFACE_DATA.Game.auto & bit) == 0 || GAME_DATA.state.checkmate) { return; } function state_score(state, player) { @@ -1887,7 +1889,7 @@ const INTERFACE = { return null; } - let result = determine_play(GAME_DATA, GAME_DATA.turn & 1, 1); + let result = determine_play(GAME_DATA, (GAME_DATA.turn + GAME_DATA.config.rules.reverse) & 1, 1); if(result !== null) { INTERFACE.process(result.play); } else { diff --git a/www/js/scene.js b/www/js/scene.js index 073954a..4bbcdfd 100644 --- a/www/js/scene.js +++ b/www/js/scene.js @@ -652,45 +652,37 @@ const SCENES = { constructor() { this.game = null; } - load() { - let buttons_bottom = [ ]; - buttons_bottom.push(UI.button(LANG("undo"), () => { INTERFACE.undo(); })); - buttons_bottom.push(UI.button(LANG("reset"), () => { INTERFACE.reset(); })); - buttons_bottom.push(UI.button(LANG("back"), () => { SCENE.load(SCENES.Browse); })); - - UI.nav([ ], buttons_bottom); - UI.mainnav([ - UI.button_piece(0, () => { - INTERFACE.load(GAME_CONFIGS.Guide_Militia); - }), - UI.button_piece(1, () => { - INTERFACE.load(GAME_CONFIGS.Guide_Lance); - }), - UI.button_piece(2, () => { - INTERFACE.load(GAME_CONFIGS.Guide_Knight); - }), - UI.button_piece(3, () => { - INTERFACE.load(GAME_CONFIGS.Guide_Tower); - }), - UI.button_piece(4, () => { - INTERFACE.load(GAME_CONFIGS.Guide_Castle); - }), - UI.button_piece(5, () => { - INTERFACE.load(GAME_CONFIGS.Guide_Dragon); - }), - UI.button_piece(6, () => { - INTERFACE.load(GAME_CONFIGS.Guide_Behemoth); - }), - UI.button_piece(7, () => { - INTERFACE.load(GAME_CONFIGS.Guide_Heart); - }), - ], []); + load(data) { + let config = GAME_CONFIGS.Guide_Militia; + if(data == null) { + UI.mainmenu_guide("guide_pieces", true); + UI.mainnav([ + UI.button_piece(0, () => { INTERFACE.load(GAME_CONFIGS.Guide_Militia); }), + UI.button_piece(1, () => { INTERFACE.load(GAME_CONFIGS.Guide_Lance); }), + UI.button_piece(2, () => { INTERFACE.load(GAME_CONFIGS.Guide_Knight); }), + UI.button_piece(3, () => { INTERFACE.load(GAME_CONFIGS.Guide_Tower); }), + UI.button_piece(4, () => { INTERFACE.load(GAME_CONFIGS.Guide_Castle); }), + UI.button_piece(5, () => { INTERFACE.load(GAME_CONFIGS.Guide_Dragon); }), + UI.button_piece(6, () => { INTERFACE.load(GAME_CONFIGS.Guide_Behemoth); }), + UI.button_piece(7, () => { INTERFACE.load(GAME_CONFIGS.Guide_Heart); }), + ], []); + } else { + UI.mainmenu_guide("guide_" + data, true); + UI.mainnav([], []); + + switch(data) { + case "drop": config = GAME_CONFIGS.Guide_Drop; break; + case "promote": config = GAME_CONFIGS.Guide_Promote; break; + case "check": config = GAME_CONFIGS.Guide_Check; break; + case "checkmate": config = GAME_CONFIGS.Guide_Checkmate; break; + } + } let canvas = document.createElement("canvas"); canvas.setAttribute("id", "game"); MAIN.appendChild(canvas); - INTERFACE.init(null, GAME_CONFIGS.Guide_Militia, INTERFACE.Mode.Local, {}); + INTERFACE.init(null, config, INTERFACE.Mode.Local, {}); history.pushState(null, "Dzura - Guide", "/guide/"); return true; diff --git a/www/js/ui.js b/www/js/ui.js index 082228b..2b29565 100644 --- a/www/js/ui.js +++ b/www/js/ui.js @@ -223,6 +223,27 @@ const UI = { UI.nav(buttons_top, buttons_bottom); }, + mainmenu_guide(page, game_buttons=false) { + let buttons_top = [ ]; + let buttons_bottom = [ ]; + + // Top Buttons + buttons_top.push(UI.button("Pieces", () => { SCENE.load(SCENES.Guide); }, page == "guide_pieces")); + buttons_top.push(UI.button("Dropping", () => { SCENE.load(SCENES.Guide, "drop"); }, page == "guide_drop")); + buttons_top.push(UI.button("Promotion", () => { SCENE.load(SCENES.Guide, "promote"); }, page == "guide_promote")); + buttons_top.push(UI.button("Check", () => { SCENE.load(SCENES.Guide, "check"); }, page == "guide_check")); + buttons_top.push(UI.button("Checkmate", () => { SCENE.load(SCENES.Guide, "checkmate"); }, page == "guide_checkmate")); + + // Bottom Buttons + if(game_buttons) { + buttons_bottom.push(UI.button(LANG("undo"), () => { INTERFACE.undo(); })); + buttons_bottom.push(UI.button(LANG("reset"), () => { INTERFACE.reset(); })); + } + buttons_bottom.push(UI.button(LANG("back"), () => { SCENE.load(SCENES.Browse); })); + + UI.nav(buttons_top, buttons_bottom); + }, + session_table(records) { let rows = [ ];