Add retire implementation.
This commit is contained in:
parent
f81e9343ce
commit
aca4e7acb1
@ -48,6 +48,7 @@ impl Game {
|
|||||||
{
|
{
|
||||||
let player = (self.turn & 1) as u8;
|
let player = (self.turn & 1) as u8;
|
||||||
|
|
||||||
|
if self.complete { return Err(()); }
|
||||||
|
|
||||||
//
|
//
|
||||||
// TODO:
|
// TODO:
|
||||||
@ -58,69 +59,82 @@ impl Game {
|
|||||||
|
|
||||||
|
|
||||||
// Move piece on board.
|
// Move piece on board.
|
||||||
if if play.source == 0 {
|
if match play.source {
|
||||||
if let Some(pid) = self.board.tiles[play.from as usize].piece {
|
0 => {
|
||||||
if let Some(mut piece) = self.board.pieces[pid as usize] {
|
if let Some(pid) = self.board.tiles[play.from as usize].piece {
|
||||||
let mut swap = false;
|
if let Some(mut piece) = self.board.pieces[pid as usize] {
|
||||||
|
let mut swap = false;
|
||||||
|
|
||||||
if let Some(tid) = self.board.tiles[play.to as usize].piece {
|
if let Some(tid) = self.board.tiles[play.to as usize].piece {
|
||||||
if let Some(target) = &mut self.board.pieces[tid as usize] {
|
if let Some(target) = &mut self.board.pieces[tid as usize] {
|
||||||
|
|
||||||
// Check for piece swap.
|
// Check for piece swap.
|
||||||
if piece.player == target.player {
|
if piece.player == target.player {
|
||||||
swap = true;
|
swap = true;
|
||||||
target.tile = play.from;
|
target.tile = play.from;
|
||||||
|
|
||||||
// Check for target promotion.
|
// Check for target promotion.
|
||||||
let hex = Hex::from_tile(play.from);
|
let hex = Hex::from_tile(play.from);
|
||||||
if !target.promoted && target.has_promotion() && Hex::is_back(hex.x, hex.y, target.player) {
|
if !target.promoted && target.has_promotion() && Hex::is_back(hex.x, hex.y, target.player) {
|
||||||
target.promoted = true;
|
target.promoted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add captured piece to pool.
|
||||||
|
else {
|
||||||
|
self.pool[piece.player as usize][target.class as usize] += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add captured piece to pool.
|
// Destroy piece if captured.
|
||||||
else {
|
if !swap { self.board.pieces[tid as usize] = None; }
|
||||||
self.pool[piece.player as usize][target.class as usize] += 1;
|
}
|
||||||
|
|
||||||
|
// Set tile/piece associations.
|
||||||
|
if swap {
|
||||||
|
self.board.tiles[play.from as usize].piece = self.board.tiles[play.to as usize].piece;
|
||||||
|
} else {
|
||||||
|
self.board.tiles[play.from as usize].piece = None;
|
||||||
|
}
|
||||||
|
self.board.tiles[play.to as usize].piece = Some(pid);
|
||||||
|
piece.tile = play.to;
|
||||||
|
|
||||||
|
self.board.pieces[pid as usize] = Some(piece);
|
||||||
|
|
||||||
|
// Check for piece promotion.
|
||||||
|
let hex = Hex::from_tile(play.to);
|
||||||
|
if !piece.promoted && piece.has_promotion() && Hex::is_back(hex.x, hex.y, piece.player) {
|
||||||
|
if let Some(piece) = &mut self.board.pieces[pid as usize] {
|
||||||
|
piece.promoted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy piece if captured.
|
self.turn += 1;
|
||||||
if !swap { self.board.pieces[tid as usize] = None; }
|
true
|
||||||
}
|
} else { false }
|
||||||
|
} else { false }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place piece from pool.
|
||||||
|
1 => {
|
||||||
|
if self.pool[player as usize][play.from as usize] > 0 && self.board.tiles[play.to as usize].piece.is_none() {
|
||||||
|
self.pool[player as usize][play.from as usize] -= 1;
|
||||||
|
let piece = Piece::new(play.from, player);
|
||||||
|
self.board.set_piece(piece, play.to);
|
||||||
|
|
||||||
// Set tile/piece associations.
|
self.turn += 1;
|
||||||
if swap {
|
|
||||||
self.board.tiles[play.from as usize].piece = self.board.tiles[play.to as usize].piece;
|
|
||||||
} else {
|
|
||||||
self.board.tiles[play.from as usize].piece = None;
|
|
||||||
}
|
|
||||||
self.board.tiles[play.to as usize].piece = Some(pid);
|
|
||||||
piece.tile = play.to;
|
|
||||||
|
|
||||||
self.board.pieces[pid as usize] = Some(piece);
|
|
||||||
|
|
||||||
// Check for piece promotion.
|
|
||||||
let hex = Hex::from_tile(play.to);
|
|
||||||
if !piece.promoted && piece.has_promotion() && Hex::is_back(hex.x, hex.y, piece.player) {
|
|
||||||
if let Some(piece) = &mut self.board.pieces[pid as usize] {
|
|
||||||
piece.promoted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
true
|
||||||
} else { false }
|
} else { false }
|
||||||
} else { false }
|
}
|
||||||
}
|
|
||||||
|
// Player retired.
|
||||||
// Place piece from pool.
|
2 => {
|
||||||
else {
|
self.complete = true;
|
||||||
if self.pool[player as usize][play.from as usize] > 0 && self.board.tiles[play.to as usize].piece.is_none() {
|
|
||||||
self.pool[player as usize][play.from as usize] -= 1;
|
|
||||||
let piece = Piece::new(play.from, player);
|
|
||||||
self.board.set_piece(piece, play.to);
|
|
||||||
true
|
true
|
||||||
} else { false }
|
}
|
||||||
|
|
||||||
|
_ => false,
|
||||||
} {
|
} {
|
||||||
self.turn += 1;
|
|
||||||
self.history.push(*play);
|
self.history.push(*play);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else { Err(()) }
|
} else { Err(()) }
|
||||||
|
@ -483,10 +483,36 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
|
|||||||
|
|
||||||
// SessionRetire
|
// SessionRetire
|
||||||
QRPacketData::QSessionRetire(request) => {
|
QRPacketData::QSessionRetire(request) => {
|
||||||
|
use game::history::Play;
|
||||||
println!("Request: Session Retire");
|
println!("Request: Session Retire");
|
||||||
|
|
||||||
if let Some(_session) = app.sessions.get_mut(&request.token) {
|
let mut packets = Vec::<QRPacket>::new();
|
||||||
|
|
||||||
|
let play = Play {
|
||||||
|
source: 2,
|
||||||
|
from: 0,
|
||||||
|
to: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(session) = app.sessions.get_mut(&request.token) {
|
||||||
|
if !session.game.complete {
|
||||||
|
session.game.process(&play).ok();
|
||||||
|
|
||||||
|
for (cid, _) in session.get_connections() {
|
||||||
|
packets.push(QRPacket::new(
|
||||||
|
cid,
|
||||||
|
QRPacketData::QGamePlay(PacketGamePlay {
|
||||||
|
status: STATUS_OK,
|
||||||
|
turn: session.game.turn,
|
||||||
|
play,
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for packet in packets {
|
||||||
|
app.send_response(packet).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(QRPacket::new(0, QRPacketData::None))
|
Some(QRPacket::new(0, QRPacketData::None))
|
||||||
@ -537,7 +563,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.p_dawn.user.is_some() && session.p_dusk.user.is_some() {
|
if !session.game.complete && (session.p_dawn.user.is_some() && session.p_dusk.user.is_some()) {
|
||||||
if (user_id == session.p_dawn.user && session.game.turn & 1 == 0)
|
if (user_id == session.p_dawn.user && session.game.turn & 1 == 0)
|
||||||
|| (user_id == session.p_dusk.user && session.game.turn & 1 == 1) {
|
|| (user_id == session.p_dusk.user && session.game.turn & 1 == 1) {
|
||||||
|
|
||||||
|
102
www/js/game.js
102
www/js/game.js
@ -204,6 +204,7 @@ GAME.Game = class {
|
|||||||
];
|
];
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
|
code:0,
|
||||||
check:false,
|
check:false,
|
||||||
checkmate:false,
|
checkmate:false,
|
||||||
};
|
};
|
||||||
@ -285,61 +286,70 @@ GAME.Game = class {
|
|||||||
// - Improve data safety validation.
|
// - Improve data safety validation.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
if(this.state.code != 0) { return false; }
|
||||||
|
|
||||||
let player = this.turn & 1;
|
let player = this.turn & 1;
|
||||||
|
|
||||||
// Move piece on board.
|
// Move piece on board.
|
||||||
if(play.source == 0) {
|
switch(play.source) {
|
||||||
let piece_id = this.board.tiles[play.from].piece;
|
case 0: {
|
||||||
let piece = this.board.pieces[piece_id];
|
let piece_id = this.board.tiles[play.from].piece;
|
||||||
piece.tile = play.to;
|
let piece = this.board.pieces[piece_id];
|
||||||
this.board.tiles[play.from].piece = null;
|
piece.tile = play.to;
|
||||||
|
this.board.tiles[play.from].piece = null;
|
||||||
|
|
||||||
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];
|
||||||
|
|
||||||
// Swap piece with moving piece.
|
// Swap piece with moving piece.
|
||||||
if(target.player == piece.player) {
|
if(target.player == piece.player) {
|
||||||
target.tile = play.from;
|
target.tile = play.from;
|
||||||
this.board.tiles[play.from].piece = target_id;
|
this.board.tiles[play.from].piece = target_id;
|
||||||
|
|
||||||
// Check if swap is promoted.
|
// Check if swap is promoted.
|
||||||
let hex = HEX.tile_to_hex(target.tile);
|
let hex = HEX.tile_to_hex(target.tile);
|
||||||
hex.y -= MATH.sign_branch(target.player);
|
hex.y -= MATH.sign_branch(target.player);
|
||||||
if(!target.promoted && target.has_promotion() && !HEX.is_valid(hex)) {
|
if(!target.promoted && target.has_promotion() && !HEX.is_valid(hex)) {
|
||||||
target.promoted = true;
|
target.promoted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add captured piece to pool and destroy.
|
||||||
|
else {
|
||||||
|
this.pools[piece.player].pieces[target.piece] += 1;
|
||||||
|
this.board.pieces[target_id] = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add captured piece to pool and destroy.
|
this.board.tiles[play.to].piece = piece_id;
|
||||||
else {
|
|
||||||
this.pools[piece.player].pieces[target.piece] += 1;
|
// Check if piece is promoted.
|
||||||
this.board.pieces[target_id] = null;
|
let hex = HEX.tile_to_hex(piece.tile);
|
||||||
|
hex.y -= MATH.sign_branch(piece.player);
|
||||||
|
if(!piece.promoted && piece.has_promotion() && !HEX.is_valid(hex)) {
|
||||||
|
piece.promoted = true;
|
||||||
}
|
}
|
||||||
}
|
this.turn++;
|
||||||
|
} break;
|
||||||
|
|
||||||
this.board.tiles[play.to].piece = piece_id;
|
// Place piece from pool.
|
||||||
|
case 1: {
|
||||||
|
this.board.set_piece(
|
||||||
|
play.from,
|
||||||
|
player,
|
||||||
|
play.to
|
||||||
|
);
|
||||||
|
this.pools[this.turn & 1].pieces[play.from] -= 1;
|
||||||
|
this.turn++;
|
||||||
|
} break;
|
||||||
|
|
||||||
// Check if piece is promoted.
|
// Play retired.
|
||||||
let hex = HEX.tile_to_hex(piece.tile);
|
case 2: {
|
||||||
hex.y -= MATH.sign_branch(piece.player);
|
this.state.code = 2;
|
||||||
if(!piece.promoted && piece.has_promotion() && !HEX.is_valid(hex)) {
|
} break;
|
||||||
piece.promoted = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Place piece from pool.
|
|
||||||
else {
|
|
||||||
this.board.set_piece(
|
|
||||||
play.from,
|
|
||||||
player,
|
|
||||||
play.to
|
|
||||||
);
|
|
||||||
this.pools[this.turn & 1].pieces[play.from] -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.turn++;
|
|
||||||
|
|
||||||
// Recalculate new board state.
|
// Recalculate new board state.
|
||||||
this.update_board();
|
this.update_board();
|
||||||
|
|
||||||
@ -550,6 +560,12 @@ GAME.Const = {
|
|||||||
Pool: 1,
|
Pool: 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
State: {
|
||||||
|
Ongoing: 0,
|
||||||
|
Complete: 1,
|
||||||
|
Retire: 2,
|
||||||
|
},
|
||||||
|
|
||||||
Direction: [
|
Direction: [
|
||||||
new MATH.Vec2(0, 1),
|
new MATH.Vec2(0, 1),
|
||||||
new MATH.Vec2(1, 1),
|
new MATH.Vec2(1, 1),
|
||||||
|
@ -563,7 +563,10 @@ const INTERFACE = {
|
|||||||
let message = null;
|
let message = null;
|
||||||
ctx.fillStyle = INTERFACE.Color.Text;
|
ctx.fillStyle = INTERFACE.Color.Text;
|
||||||
|
|
||||||
if(GAME_DATA.state.check) {
|
if(GAME_DATA.state.code == GAME.Const.State.Retire) {
|
||||||
|
ctx.fillStyle = INTERFACE.Color.HintCheck;
|
||||||
|
message = "Retire";
|
||||||
|
} else if(GAME_DATA.state.check) {
|
||||||
ctx.fillStyle = INTERFACE.Color.HintCheck;
|
ctx.fillStyle = INTERFACE.Color.HintCheck;
|
||||||
if(GAME_DATA.state.checkmate) {
|
if(GAME_DATA.state.checkmate) {
|
||||||
message = "Checkmate";
|
message = "Checkmate";
|
||||||
@ -716,6 +719,7 @@ const INTERFACE = {
|
|||||||
handles: [null, null],
|
handles: [null, null],
|
||||||
board_state: [ ],
|
board_state: [ ],
|
||||||
play: null,
|
play: null,
|
||||||
|
retire:false,
|
||||||
|
|
||||||
Ui: {
|
Ui: {
|
||||||
scale: 0,
|
scale: 0,
|
||||||
@ -778,6 +782,10 @@ const INTERFACE = {
|
|||||||
GAME_DATA.turn = data.turn;
|
GAME_DATA.turn = data.turn;
|
||||||
INTERFACE_DATA.play = data.play;
|
INTERFACE_DATA.play = data.play;
|
||||||
|
|
||||||
|
if(INTERFACE_DATA.play.source == 2) {
|
||||||
|
GAME_DATA.state.code = 2;
|
||||||
|
}
|
||||||
|
|
||||||
if(data.dawn.length > 0) { INTERFACE_DATA.handles[0] = data.dawn; }
|
if(data.dawn.length > 0) { INTERFACE_DATA.handles[0] = data.dawn; }
|
||||||
if(data.dusk.length > 0) { INTERFACE_DATA.handles[1] = data.dusk; }
|
if(data.dusk.length > 0) { INTERFACE_DATA.handles[1] = data.dusk; }
|
||||||
|
|
||||||
|
@ -10,9 +10,12 @@ LANGUAGE.Terms = {
|
|||||||
Dawn: new LANGUAGE.Term( "Dawn", "暁" ),
|
Dawn: new LANGUAGE.Term( "Dawn", "暁" ),
|
||||||
Dusk: new LANGUAGE.Term( "Dusk", "黄昏" ),
|
Dusk: new LANGUAGE.Term( "Dusk", "黄昏" ),
|
||||||
|
|
||||||
Handle: new LANGUAGE.Term( "Handle", "" ),
|
Handle: new LANGUAGE.Term( "Handle", "" ),
|
||||||
Secret: new LANGUAGE.Term( "Secret", "" ),
|
Secret: new LANGUAGE.Term( "Secret", "" ),
|
||||||
|
|
||||||
Browse: new LANGUAGE.Term( "Resume", "" ),
|
Browse: new LANGUAGE.Term( "Browse", "" ),
|
||||||
Resume: new LANGUAGE.Term( "Resume", "" ),
|
Resume: new LANGUAGE.Term( "Resume", "" ),
|
||||||
|
|
||||||
|
Check: new LANGUAGE.Term( "Check", "王手" ),
|
||||||
|
Checkmate: new LANGUAGE.Term( "Checkmate", "詰み" ),
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user