diff options
Diffstat (limited to 'rules.js')
-rw-r--r-- | rules.js | 183 |
1 files changed, 132 insertions, 51 deletions
@@ -1,5 +1,7 @@ "use strict" +const DEBUG = 0 + const R_LOUIS_XV = "Louis XV" const R_FREDERICK = "Frederick" const R_MARIA_THERESA = "Maria Theresa" @@ -98,10 +100,11 @@ const F_SAXONY_TC_ONCE = 128 // only draw TCs once per turn const F_FRANCE_REDUCED = 256 const F_PRUSSIA_NEUTRAL = 512 const F_MOVE_FLANDERS = 1024 -const F_INTRODUCTORY = 2048 -const F_TWO_PLAYER = 4096 -const F_PLAYER_A_PICK = 8192 // picked PC card -const F_PLAYER_B_PICK = 16384 +const F_MOVE_COOP = 2048 +const F_INTRODUCTORY = 4096 +const F_TWO_PLAYER = 8192 +const F_PLAYER_A_PICK = 16384 // picked PC card +const F_PLAYER_B_PICK = 32768 const SPADES = 0 const CLUBS = 1 @@ -1377,6 +1380,7 @@ const advanced_sequence_of_play = [ // alternate moves on flanders starting with pragmatic army { power: P_PRAGMATIC, action: init_movement }, + { power: P_PRAGMATIC, action: goto_movement_coop }, { power: P_PRAGMATIC, action: goto_movement_flanders }, { power: P_AUSTRIA, action: goto_movement_flanders }, { power: P_PRAGMATIC, action: goto_movement_flanders }, @@ -2282,6 +2286,20 @@ function init_movement() { next_sequence_of_play() } +function has_unmoved_piece(pow) { + for (let p of all_controlled_pieces(pow)) + if (!set_has(game.moved, p)) + return true + return false +} + +function has_moved_piece_on_flanders_map(pow) { + for (let p of all_power_pieces[pow]) + if (is_flanders_space(game.pos[p]) && set_has(game.moved, p)) + return true + return false +} + function has_unmoved_piece_on_flanders_map(pow) { for (let p of all_power_pieces[pow]) if (is_flanders_space(game.pos[p]) && !set_has(game.moved, p)) @@ -2300,6 +2318,18 @@ function goto_movement_global() { game.state = "movement" } +function goto_movement_coop() { + game.state = "movement" + game.flags |= F_MOVE_FLANDERS + + clear_undo() + push_undo() + game.restart = game.undo[0] + clear_undo() + + game.flags |= F_MOVE_COOP +} + function goto_movement_flanders() { game.flags |= F_MOVE_FLANDERS game.state = "movement" @@ -2320,7 +2350,8 @@ function resume_movement() { game.power = P_AUSTRIA set_active_to_power(coop_major_power(game.power)) game.selected = -1 - if (game.flags & F_MOVE_FLANDERS) { + + if ((game.flags & F_MOVE_FLANDERS) && !(game.flags & F_MOVE_COOP)) { let row = advanced_sequence_of_play[game.stage+1] if (row.action === goto_movement_flanders) { let next = game.power === P_PRAGMATIC ? P_AUSTRIA : P_PRAGMATIC @@ -2396,6 +2427,14 @@ function can_general_move_anywhere(p) { return false } +function may_dispute_flanders_movement() { + if (game.power === P_PRAGMATIC && has_moved_piece_on_flanders_map(P_AUSTRIA)) + return true + if (game.power === P_AUSTRIA) + return true + return false +} + states.movement_flanders_next = { inactive: "move", prompt() { @@ -2410,41 +2449,6 @@ states.movement_flanders_next = { }, } -function has_moved_any_pieces() { - if (!is_two_player()) { - if (game.power === P_AUSTRIA && !(game.flags & F_MOVE_FLANDERS)) - return has_moved_any_bohemia_pieces() - } - for (let p of all_controlled_generals(game.power)) - if (set_has(game.moved, p)) - return true - for (let p of all_controlled_trains(game.power)) - if (set_has(game.moved, p)) - return true - return false -} - -function has_moved_any_bohemia_pieces() { - for (let p of all_controlled_generals(game.power)) - if (is_bohemia_space(game.pos[p]) && set_has(game.moved, p)) - return true - for (let p of all_controlled_trains(game.power)) - if (is_bohemia_space(game.pos[p]) && set_has(game.moved, p)) - return true - return false -} - -function may_end_movement() { - if (game.flags & F_MOVE_FLANDERS) { - // No passing of movement on Flanders map while alternating moves. - if (game.power === P_AUSTRIA) - return !has_unmoved_piece_on_flanders_map(P_PRAGMATIC) - if (game.power === P_PRAGMATIC) - return !has_unmoved_piece_on_flanders_map(P_AUSTRIA) - } - return true -} - states.movement = { inactive: "move", prompt() { @@ -2479,8 +2483,8 @@ states.movement = { } } - if (game.power === P_AUSTRIA && (game.flags & F_MOVE_FLANDERS)) - prompt("Move one piece on the Flanders map.") + if (game.flags & F_MOVE_FLANDERS) + prompt("Move pieces on the Flanders map.") else if (done_trains && done_generals) prompt("Movement done.") else if (done_generals && !done_trains) @@ -2490,11 +2494,37 @@ states.movement = { else prompt("Move your generals and supply trains.") - if (may_end_movement()) { - if (!has_moved_any_pieces()) - view.actions.confirm_end_movement = 1 + if (game.flags & F_MOVE_COOP) { + if (may_dispute_flanders_movement()) + view.actions.dispute = 1 + else + view.actions.dispute = 0 + if (game.power === P_PRAGMATIC && has_unmoved_piece_on_flanders_map(P_AUSTRIA)) + gen_action_power(P_AUSTRIA) + if (game.power === P_AUSTRIA && has_unmoved_piece_on_flanders_map(P_PRAGMATIC)) + gen_action_power(P_PRAGMATIC) + } + + if (game.flags & F_MOVE_FLANDERS) { + if (game.restart) + view.actions.restart = 1 + if (!has_unmoved_piece_on_flanders_map(P_PRAGMATIC) && !has_unmoved_piece_on_flanders_map(P_AUSTRIA)) + view.actions.end_flanders = 1 else - view.actions.end_movement = 1 + view.actions.end_flanders = 0 + } else { + if (DEBUG || !has_unmoved_piece(game.power)) { + if (game.power === P_AUSTRIA && !is_two_player()) + view.actions.end_bohemia = 1 + else + view.actions.end_movement = 1 + } else { + if (game.power === P_AUSTRIA && !is_two_player()) + view.actions.end_bohemia = 0 + else + view.actions.end_movement = 0 + } + } }, piece(p) { @@ -2528,13 +2558,60 @@ states.movement = { }, end_movement() { push_undo() - if (game.flags & F_MOVE_FLANDERS) { - for (let p of all_power_pieces[game.power]) - if (is_flanders_space(game.pos[p])) - set_add(game.moved, p) - } next_sequence_of_play() }, + end_bohemia() { + this.end_movement() + }, + end_flanders() { + push_undo() + game.flags &= ~F_MOVE_COOP + delete game.restart + next_sequence_of_play() + }, + power(pow) { + // cooperative on flanders map + set_active_to_power(pow) + }, + restart() { + clear_undo() + game.undo = [ game.restart ] + delete game.restart + pop_undo() + goto_movement_coop() + game.state = "restart_flanders_movement" + }, + dispute() { + // enter non-coop mode + clear_undo() + game.undo = [ game.restart ] + delete game.restart + pop_undo() + game.state = "dispute_flanders_movement" + }, +} + +states.restart_flanders_movement = { + inactive: "move", + prompt() { + prompt("Reset moves on Flanders map due to request.") + view.actions.next = 1 + }, + next() { + game.state = "movement" + }, +} + +states.dispute_flanders_movement = { + inactive: "move", + prompt() { + prompt("Alternating moves on Flanders map due to dispute.") + view.actions.next = 1 + }, + next() { + log("Alternating moves.") + next_sequence_of_play() // jump to non-coop movement + }, } function end_movement() { @@ -6779,6 +6856,8 @@ function push_undo() { let v = game[k] if (k === "deals") continue + if (k === "restart") + continue if (k === "undo") continue else if (k === "log") @@ -6796,11 +6875,13 @@ function pop_undo() { let save_log = game.log let save_undo = game.undo let save_deals = game.deals + let save_restart = game.restart game = save_undo.pop() save_log.length = game.log game.log = save_log game.undo = save_undo game.deals = save_deals + game.restart = save_restart } } |