chess: pawn promotion
For a lack of a better idea, bind board and piece rotation to X/Y chess::do_move no longer advances the turn--prior to this change, castle moves incorrectly double-negated turn.
This commit is contained in:
parent
ebb1955500
commit
bf9a862a43
Binary file not shown.
@ -82,6 +82,9 @@ move_t * moves_pawn(game_state& game_state, int8_t origin, move_t * moves)
|
|||||||
if (other.type == 0) {
|
if (other.type == 0) {
|
||||||
int8_t to_position = xy_to_position(x, y);
|
int8_t to_position = xy_to_position(x, y);
|
||||||
if (!speculative_check(game_state, origin, to_position, self.type)) {
|
if (!speculative_check(game_state, origin, to_position, self.type)) {
|
||||||
|
if (y == 0 || y == 7) {
|
||||||
|
type = move_type::pawn_promote;
|
||||||
|
}
|
||||||
*moves++ = {type, to_position};
|
*moves++ = {type, to_position};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -289,6 +292,8 @@ void game_init(game_state& game_state)
|
|||||||
game_state.interaction.selected_position = -1;
|
game_state.interaction.selected_position = -1;
|
||||||
game_state.interaction.last_move.from_position = -1;
|
game_state.interaction.last_move.from_position = -1;
|
||||||
game_state.interaction.last_move.to_position = -1;
|
game_state.interaction.last_move.to_position = -1;
|
||||||
|
game_state.interaction.promotion_ix[0] = 0;
|
||||||
|
game_state.interaction.promotion_ix[1] = 0;
|
||||||
board_init(game_state);
|
board_init(game_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,6 +411,15 @@ void do_move(game_state& game_state, int8_t from_position, move_t& move)
|
|||||||
piece_list_delete(game_state.piece_list, en_passant_piece.piece_list_offset);
|
piece_list_delete(game_state.piece_list, en_passant_piece.piece_list_offset);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case move_type::pawn_promote:
|
||||||
|
{
|
||||||
|
serial::string("move pawn promote\n");
|
||||||
|
if (origin.type > 0)
|
||||||
|
origin.type = promotion_types[game_state.interaction.promotion_ix[0]];
|
||||||
|
else
|
||||||
|
origin.type = -promotion_types[game_state.interaction.promotion_ix[1]];
|
||||||
|
}
|
||||||
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,8 +430,6 @@ void do_move(game_state& game_state, int8_t from_position, move_t& move)
|
|||||||
game_state.piece_list.piece[origin.piece_list_offset] = &destination;
|
game_state.piece_list.piece[origin.piece_list_offset] = &destination;
|
||||||
game_state.interaction.last_move.from_position = from_position;
|
game_state.interaction.last_move.from_position = from_position;
|
||||||
game_state.interaction.last_move.to_position = move.to_position;
|
game_state.interaction.last_move.to_position = move.to_position;
|
||||||
|
|
||||||
game_state.turn = -game_state.turn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void select_position(game_state& game_state, int8_t x, int8_t y)
|
void select_position(game_state& game_state, int8_t x, int8_t y)
|
||||||
@ -439,6 +451,7 @@ void select_position(game_state& game_state, int8_t x, int8_t y)
|
|||||||
do_move(game_state,
|
do_move(game_state,
|
||||||
game_state.interaction.selected_position, // from
|
game_state.interaction.selected_position, // from
|
||||||
game_state.interaction.moves.moves[moves_ix]); // to
|
game_state.interaction.moves.moves[moves_ix]); // to
|
||||||
|
game_state.turn = -game_state.turn;
|
||||||
// fall through to deselect
|
// fall through to deselect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,13 @@ constexpr int8_t queen = 5;
|
|||||||
constexpr int8_t king = 6;
|
constexpr int8_t king = 6;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr int8_t promotion_types[4] = {
|
||||||
|
piece_type::knight,
|
||||||
|
piece_type::bishop,
|
||||||
|
piece_type::rook,
|
||||||
|
piece_type::queen,
|
||||||
|
};
|
||||||
|
|
||||||
namespace movement_state {
|
namespace movement_state {
|
||||||
constexpr int8_t not_moved = 0;
|
constexpr int8_t not_moved = 0;
|
||||||
constexpr int8_t moved = 1;
|
constexpr int8_t moved = 1;
|
||||||
@ -45,6 +52,7 @@ enum struct move_type : int8_t {
|
|||||||
castle_long,
|
castle_long,
|
||||||
pawn_double_advance,
|
pawn_double_advance,
|
||||||
pawn_en_passant_capture,
|
pawn_en_passant_capture,
|
||||||
|
pawn_promote,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct move_t {
|
struct move_t {
|
||||||
@ -81,6 +89,7 @@ struct interaction_state {
|
|||||||
int8_t selected_position;
|
int8_t selected_position;
|
||||||
struct moves_list moves;
|
struct moves_list moves;
|
||||||
struct annotation_list annotation_list;
|
struct annotation_list annotation_list;
|
||||||
|
int8_t promotion_ix[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct game_state {
|
struct game_state {
|
||||||
|
@ -46,6 +46,8 @@ void cursor_update(struct render::cursor_state& cursor_state, uint32_t frame_ix)
|
|||||||
cursor.y += static_cast<float>(data.analog_coordinate_axis[3] - 0x80) * -0.0015 * invert;
|
cursor.y += static_cast<float>(data.analog_coordinate_axis[3] - 0x80) * -0.0015 * invert;
|
||||||
cursor.button[frame_ix].a = ft0::data_transfer::digital_button::a(data.digital_button) == 0;
|
cursor.button[frame_ix].a = ft0::data_transfer::digital_button::a(data.digital_button) == 0;
|
||||||
cursor.button[frame_ix].b = ft0::data_transfer::digital_button::b(data.digital_button) == 0;
|
cursor.button[frame_ix].b = ft0::data_transfer::digital_button::b(data.digital_button) == 0;
|
||||||
|
cursor.button[frame_ix].x = ft0::data_transfer::digital_button::x(data.digital_button) == 0;
|
||||||
|
cursor.button[frame_ix].y = ft0::data_transfer::digital_button::y(data.digital_button) == 0;
|
||||||
bool start = ft0::data_transfer::digital_button::start(data.digital_button) == 0;
|
bool start = ft0::data_transfer::digital_button::start(data.digital_button) == 0;
|
||||||
if (start) {
|
if (start) {
|
||||||
cursor.x = 3.5f;
|
cursor.x = 3.5f;
|
||||||
@ -70,27 +72,56 @@ void cursor_update(struct render::cursor_state& cursor_state, uint32_t frame_ix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor.x < -1.0f) cursor.x = -1.0f;
|
if (cursor.x < -2.0f) cursor.x = -2.0f;
|
||||||
if (cursor.x > 8.0f) cursor.x = 8.0f;
|
if (cursor.x > 9.0f) cursor.x = 9.0f;
|
||||||
if (cursor.y < -0.5f) cursor.y = -0.5f;
|
if (cursor.y < -0.5f) cursor.y = -0.5f;
|
||||||
if (cursor.y > 7.5f) cursor.y = 7.5f;
|
if (cursor.y > 7.5f) cursor.y = 7.5f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool piece_rotation = false;
|
||||||
|
static bool board_rotation = false;
|
||||||
|
|
||||||
|
void promotion_select(chess::game_state& game_state,
|
||||||
|
int side,
|
||||||
|
int promotion_ix)
|
||||||
|
{
|
||||||
|
if (promotion_ix < 0 || promotion_ix >= 4) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
game_state.interaction.promotion_ix[side] = promotion_ix;
|
||||||
|
}
|
||||||
|
|
||||||
void cursor_events(chess::game_state& game_state, struct render::cursor_state& cursor_state, uint32_t frame_ix)
|
void cursor_events(chess::game_state& game_state, struct render::cursor_state& cursor_state, uint32_t frame_ix)
|
||||||
{
|
{
|
||||||
for (int cursor_ix = 0; cursor_ix < render::cursor_state::num_cursors; cursor_ix++) {
|
for (int cursor_ix = 0; cursor_ix < render::cursor_state::num_cursors; cursor_ix++) {
|
||||||
auto& cursor = cursor_state.cur[cursor_ix];
|
auto& cursor = cursor_state.cur[cursor_ix];
|
||||||
const uint32_t last_frame = (frame_ix + 1) & 1;
|
const uint32_t last_frame = (frame_ix + 1) & 1;
|
||||||
const int8_t x = cursor.x + 0.5f;
|
const float x = cursor.x + 0.5f;
|
||||||
const int8_t y = cursor.y + 0.5f;
|
const int8_t y = cursor.y + 0.5f;
|
||||||
if (cursor.button[last_frame].a != cursor.button[frame_ix].a && cursor.button[frame_ix].a) {
|
if (cursor.button[last_frame].a != cursor.button[frame_ix].a && cursor.button[frame_ix].a) {
|
||||||
chess::clear_annotations(game_state);
|
chess::clear_annotations(game_state);
|
||||||
|
if (x > 8.5) {
|
||||||
|
serial::string("white side\n");
|
||||||
|
int8_t promotion_ix = y;
|
||||||
|
promotion_select(game_state, 0, promotion_ix);
|
||||||
|
} else if (x < -0.5) {
|
||||||
|
serial::string("black side\n");
|
||||||
|
int8_t promotion_ix = 7 - y;
|
||||||
|
promotion_select(game_state, 1, promotion_ix);
|
||||||
|
} else {
|
||||||
chess::select_position(game_state, x, y);
|
chess::select_position(game_state, x, y);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (cursor.button[last_frame].b != cursor.button[frame_ix].b && cursor.button[frame_ix].b) {
|
if (cursor.button[last_frame].b != cursor.button[frame_ix].b && cursor.button[frame_ix].b) {
|
||||||
chess::annotate_position(game_state, x, y);
|
chess::annotate_position(game_state, x, y);
|
||||||
}
|
}
|
||||||
|
if (cursor.button[last_frame].x != cursor.button[frame_ix].x && cursor.button[frame_ix].x) {
|
||||||
|
piece_rotation = !piece_rotation;
|
||||||
|
}
|
||||||
|
if (cursor.button[last_frame].y != cursor.button[frame_ix].y && cursor.button[frame_ix].y) {
|
||||||
|
board_rotation = !board_rotation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,27 +165,31 @@ void main()
|
|||||||
vt.board_rotation = 0.f;
|
vt.board_rotation = 0.f;
|
||||||
|
|
||||||
auto piece_rotation_animator = render::animator<float>(0.f);
|
auto piece_rotation_animator = render::animator<float>(0.f);
|
||||||
|
auto board_rotation_animator = render::animator<float>(0.f);
|
||||||
|
|
||||||
struct render::cursor_state cursor_state = render::cursor_state();
|
struct render::cursor_state cursor_state = render::cursor_state();
|
||||||
|
|
||||||
constexpr float pi = 3.141592653589793f;
|
constexpr float pi = 3.141592653589793f;
|
||||||
|
piece_rotation = false;
|
||||||
|
board_rotation = false;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
input::state_update(send_buf, recv_buf);
|
input::state_update(send_buf, recv_buf);
|
||||||
cursor_update(cursor_state, frame_ix);
|
cursor_update(cursor_state, frame_ix);
|
||||||
cursor_events(game_state, cursor_state, frame_ix);
|
cursor_events(game_state, cursor_state, frame_ix);
|
||||||
|
|
||||||
float target = game_state.turn == 1 ? 0.f : pi;
|
//float target = game_state.turn == 1 ? 0.f : pi;
|
||||||
piece_rotation_animator.set_target(target, 60);
|
piece_rotation_animator.set_target(piece_rotation ? pi : 0.f, 60);
|
||||||
//vt.board_rotation = piece_rotation_animator.interpolate();
|
board_rotation_animator.set_target(board_rotation ? pi : 0.f, 60);
|
||||||
//vt.piece_rotation = piece_rotation_animator.interpolate();
|
vt.board_rotation = board_rotation_animator.interpolate();
|
||||||
|
vt.piece_rotation = piece_rotation_animator.interpolate();
|
||||||
|
|
||||||
ta_polygon_converter_init(opb_size.total(),
|
ta_polygon_converter_init(opb_size.total(),
|
||||||
ta_alloc,
|
ta_alloc,
|
||||||
640 / 32,
|
640 / 32,
|
||||||
480 / 32);
|
480 / 32);
|
||||||
|
|
||||||
render::render(game_state, vt, cursor_state);
|
render::render(vt, game_state, cursor_state);
|
||||||
|
|
||||||
*reinterpret_cast<ta_global_parameter::end_of_list *>(store_queue) =
|
*reinterpret_cast<ta_global_parameter::end_of_list *>(store_queue) =
|
||||||
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
||||||
|
@ -190,7 +190,7 @@ void draw_moves(const view_transform vt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void draw_piece(const view_transform vt,
|
void draw_piece(const view_transform vt,
|
||||||
int8_t type, int8_t x, int8_t y)
|
int8_t type, float x, float y)
|
||||||
{
|
{
|
||||||
bool white = type > 0;
|
bool white = type > 0;
|
||||||
uint32_t color = white ? 0xffdddddd : 0xff444444;
|
uint32_t color = white ? 0xffdddddd : 0xff444444;
|
||||||
@ -337,8 +337,50 @@ void draw_interaction(const view_transform vt,
|
|||||||
render::draw_illumination(vt, interaction.last_move.to_position, yellow_highlight);
|
render::draw_illumination(vt, interaction.last_move.to_position, yellow_highlight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(const chess::game_state& game_state,
|
void draw_promotion_selection(const view_transform vt,
|
||||||
const view_transform vt,
|
const chess::game_state& game_state)
|
||||||
|
{
|
||||||
|
constexpr uint32_t yellow_highlight = 0x7fffff33;
|
||||||
|
|
||||||
|
draw_model(vt,
|
||||||
|
square::vertices,
|
||||||
|
square::faces,
|
||||||
|
square::num_faces,
|
||||||
|
yellow_highlight,
|
||||||
|
8.5f, game_state.interaction.promotion_ix[0],
|
||||||
|
illumination_z,
|
||||||
|
1.0f, // scale
|
||||||
|
0.0f, // rotation
|
||||||
|
true, // always
|
||||||
|
true); // alpha
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
draw_piece(vt,
|
||||||
|
chess::promotion_types[i],
|
||||||
|
8.5f, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_model(vt,
|
||||||
|
square::vertices,
|
||||||
|
square::faces,
|
||||||
|
square::num_faces,
|
||||||
|
yellow_highlight,
|
||||||
|
-1.5f, 7 - game_state.interaction.promotion_ix[1],
|
||||||
|
illumination_z,
|
||||||
|
1.0f, // scale
|
||||||
|
0.0f, // rotation
|
||||||
|
true, // always
|
||||||
|
true); // alpha
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
draw_piece(vt,
|
||||||
|
-chess::promotion_types[i],
|
||||||
|
-1.5f, 7 - i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void render(const view_transform vt,
|
||||||
|
const chess::game_state& game_state,
|
||||||
const cursor_state cursor_state)
|
const cursor_state cursor_state)
|
||||||
{
|
{
|
||||||
render::draw_board(vt);
|
render::draw_board(vt);
|
||||||
@ -347,6 +389,8 @@ void render(const chess::game_state& game_state,
|
|||||||
render::draw_annotation(vt, game_state.interaction.annotation_list);
|
render::draw_annotation(vt, game_state.interaction.annotation_list);
|
||||||
|
|
||||||
render::draw_pieces(vt, game_state);
|
render::draw_pieces(vt, game_state);
|
||||||
|
render::draw_promotion_selection(vt, game_state);
|
||||||
|
|
||||||
render::draw_moves(vt, game_state.interaction.moves);
|
render::draw_moves(vt, game_state.interaction.moves);
|
||||||
for (int i = 0; i < cursor_state::num_cursors; i++) {
|
for (int i = 0; i < cursor_state::num_cursors; i++) {
|
||||||
auto& cursor = cursor_state.cur[i];
|
auto& cursor = cursor_state.cur[i];
|
||||||
|
@ -46,6 +46,8 @@ struct animator {
|
|||||||
struct button {
|
struct button {
|
||||||
bool a;
|
bool a;
|
||||||
bool b;
|
bool b;
|
||||||
|
bool x;
|
||||||
|
bool y;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cursor {
|
struct cursor {
|
||||||
@ -78,8 +80,8 @@ struct cursor_state {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void render(const chess::game_state& game_state,
|
void render(const view_transform vt,
|
||||||
const view_transform vt,
|
const chess::game_state& game_state,
|
||||||
const cursor_state cursor_state);
|
const cursor_state cursor_state);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user